summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling/Refactoring
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Tooling/Refactoring')
-rw-r--r--clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp179
-rw-r--r--clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp90
2 files changed, 72 insertions, 197 deletions
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
index f36387dafdb..3bfb5bbe35e 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRFinder.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
@@ -25,132 +26,38 @@ using namespace llvm;
namespace clang {
namespace tooling {
-// NamedDeclFindingASTVisitor recursively visits each AST node to find the
-// symbol underneath the cursor.
-// FIXME: move to separate .h/.cc file if this gets too large.
namespace {
-class NamedDeclFindingASTVisitor
- : public clang::RecursiveASTVisitor<NamedDeclFindingASTVisitor> {
+
+/// Recursively visits each AST node to find the symbol underneath the cursor.
+class NamedDeclOccurrenceFindingVisitor
+ : public RecursiveSymbolVisitor<NamedDeclOccurrenceFindingVisitor> {
public:
// \brief Finds the NamedDecl at a point in the source.
// \param Point the location in the source to search for the NamedDecl.
- explicit NamedDeclFindingASTVisitor(const SourceLocation Point,
- const ASTContext &Context)
- : Result(nullptr), Point(Point), Context(Context) {}
-
- // \brief Finds the NamedDecl for a name in the source.
- // \param Name the fully qualified name.
- explicit NamedDeclFindingASTVisitor(const std::string &Name,
- const ASTContext &Context)
- : Result(nullptr), Name(Name), Context(Context) {}
-
- // Declaration visitors:
-
- // \brief Checks if the point falls within the NameDecl. This covers every
- // declaration of a named entity that we may come across. Usually, just
- // checking if the point lies within the length of the name of the declaration
- // and the start location is sufficient.
- bool VisitNamedDecl(const NamedDecl *Decl) {
- return dyn_cast<CXXConversionDecl>(Decl)
- ? true
- : setResult(Decl, Decl->getLocation(),
- Decl->getNameAsString().length());
- }
-
- // Expression visitors:
-
- bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl();
- return setResult(Decl, Expr->getLocation(),
- Decl->getNameAsString().length());
- }
-
- bool VisitMemberExpr(const MemberExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl().getDecl();
- return setResult(Decl, Expr->getMemberLoc(),
- Decl->getNameAsString().length());
- }
-
- // Other visitors:
-
- bool VisitTypeLoc(const TypeLoc Loc) {
- const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
- const SourceLocation TypeEndLoc = Lexer::getLocForEndOfToken(
- TypeBeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
- if (const auto *TemplateTypeParm =
- dyn_cast<TemplateTypeParmType>(Loc.getType()))
- return setResult(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc);
- if (const auto *TemplateSpecType =
- dyn_cast<TemplateSpecializationType>(Loc.getType())) {
- return setResult(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
- TypeBeginLoc, TypeEndLoc);
- }
- return setResult(Loc.getType()->getAsCXXRecordDecl(), TypeBeginLoc,
- TypeEndLoc);
- }
-
- bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
- for (const auto *Initializer : ConstructorDecl->inits()) {
- // Ignore implicit initializers.
- if (!Initializer->isWritten())
- continue;
- if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
- const SourceLocation InitBeginLoc = Initializer->getSourceLocation(),
- InitEndLoc = Lexer::getLocForEndOfToken(
- InitBeginLoc, 0, Context.getSourceManager(),
- Context.getLangOpts());
- if (!setResult(FieldDecl, InitBeginLoc, InitEndLoc))
- return false;
- }
- }
- return true;
- }
-
- // Other:
-
- const NamedDecl *getNamedDecl() { return Result; }
-
- // \brief Determines if a namespace qualifier contains the point.
- // \returns false on success and sets Result.
- void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
- while (NameLoc) {
- const NamespaceDecl *Decl =
- NameLoc.getNestedNameSpecifier()->getAsNamespace();
- setResult(Decl, NameLoc.getLocalBeginLoc(), NameLoc.getLocalEndLoc());
- NameLoc = NameLoc.getPrefix();
- }
- }
-
-private:
- // \brief Sets Result to Decl if the Point is within Start and End.
- // \returns false on success.
- bool setResult(const NamedDecl *Decl, SourceLocation Start,
- SourceLocation End) {
- if (!Decl)
+ explicit NamedDeclOccurrenceFindingVisitor(const SourceLocation Point,
+ const ASTContext &Context)
+ : RecursiveSymbolVisitor(Context.getSourceManager(),
+ Context.getLangOpts()),
+ Point(Point), Context(Context) {}
+
+ bool visitSymbolOccurrence(const NamedDecl *ND,
+ ArrayRef<SourceRange> NameRanges) {
+ if (!ND)
return true;
- if (Name.empty()) {
- // Offset is used to find the declaration.
+ for (const auto &Range : NameRanges) {
+ SourceLocation Start = Range.getBegin();
+ SourceLocation End = Range.getEnd();
if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
!End.isFileID() || !isPointWithin(Start, End))
return true;
- } else {
- // Fully qualified name is used to find the declaration.
- if (Name != Decl->getQualifiedNameAsString() &&
- Name != "::" + Decl->getQualifiedNameAsString())
- return true;
}
- Result = Decl;
+ Result = ND;
return false;
}
- // \brief Sets Result to Decl if Point is within Loc and Loc + Offset.
- // \returns false on success.
- bool setResult(const NamedDecl *Decl, SourceLocation Loc, unsigned Offset) {
- // FIXME: Add test for Offset == 0. Add test for Offset - 1 (vs -2 etc).
- return Offset == 0 ||
- setResult(Decl, Loc, Loc.getLocWithOffset(Offset - 1));
- }
+ const NamedDecl *getNamedDecl() const { return Result; }
+private:
// \brief Determines if the Point is within Start and End.
bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
// FIXME: Add tests for Point == End.
@@ -160,17 +67,17 @@ private:
Context.getSourceManager().isBeforeInTranslationUnit(Point, End));
}
- const NamedDecl *Result;
+ const NamedDecl *Result = nullptr;
const SourceLocation Point; // The location to find the NamedDecl.
- const std::string Name;
const ASTContext &Context;
};
-} // namespace
+
+} // end anonymous namespace
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point) {
const SourceManager &SM = Context.getSourceManager();
- NamedDeclFindingASTVisitor Visitor(Point, Context);
+ NamedDeclOccurrenceFindingVisitor Visitor(Point, Context);
// Try to be clever about pruning down the number of top-level declarations we
// see. If both start and end is either before or after the point we're
@@ -184,18 +91,44 @@ const NamedDecl *getNamedDeclAt(const ASTContext &Context,
Visitor.TraverseDecl(CurrDecl);
}
- NestedNameSpecifierLocFinder Finder(const_cast<ASTContext &>(Context));
- for (const auto &Location : Finder.getNestedNameSpecifierLocations())
- Visitor.handleNestedNameSpecifierLoc(Location);
-
return Visitor.getNamedDecl();
}
+namespace {
+
+/// Recursively visits each NamedDecl node to find the declaration with a
+/// specific name.
+class NamedDeclFindingVisitor
+ : public RecursiveASTVisitor<NamedDeclFindingVisitor> {
+public:
+ explicit NamedDeclFindingVisitor(StringRef Name) : Name(Name) {}
+
+ // We don't have to traverse the uses to find some declaration with a
+ // specific name, so just visit the named declarations.
+ bool VisitNamedDecl(const NamedDecl *ND) {
+ if (!ND)
+ return true;
+ // Fully qualified name is used to find the declaration.
+ if (Name != ND->getQualifiedNameAsString() &&
+ Name != "::" + ND->getQualifiedNameAsString())
+ return true;
+ Result = ND;
+ return false;
+ }
+
+ const NamedDecl *getNamedDecl() const { return Result; }
+
+private:
+ const NamedDecl *Result = nullptr;
+ StringRef Name;
+};
+
+} // end anonymous namespace
+
const NamedDecl *getNamedDeclFor(const ASTContext &Context,
const std::string &Name) {
- NamedDeclFindingASTVisitor Visitor(Name, Context);
+ NamedDeclFindingVisitor Visitor(Name);
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
-
return Visitor.getNamedDecl();
}
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index 934507fe6ea..dc21a94610c 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -22,6 +22,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/Core/Lookup.h"
+#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
#include "clang/Tooling/Refactoring/Rename/USRFinder.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
@@ -40,70 +41,27 @@ namespace {
// \brief This visitor recursively searches for all instances of a USR in a
// translation unit and stores them for later usage.
class USRLocFindingASTVisitor
- : public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
+ : public RecursiveSymbolVisitor<USRLocFindingASTVisitor> {
public:
explicit USRLocFindingASTVisitor(const std::vector<std::string> &USRs,
StringRef PrevName,
const ASTContext &Context)
- : USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
+ : RecursiveSymbolVisitor(Context.getSourceManager(),
+ Context.getLangOpts()),
+ USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
}
- // Declaration visitors:
-
- bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
- for (const auto *Initializer : ConstructorDecl->inits()) {
- // Ignore implicit initializers.
- if (!Initializer->isWritten())
- continue;
- if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
- if (USRSet.find(getUSRForDecl(FieldDecl)) != USRSet.end())
- LocationsFound.push_back(Initializer->getSourceLocation());
- }
- }
- return true;
- }
-
- bool VisitNamedDecl(const NamedDecl *Decl) {
- if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end())
- checkAndAddLocation(Decl->getLocation());
- return true;
- }
-
- // Expression visitors:
-
- bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl();
-
- if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end()) {
- const SourceManager &Manager = Decl->getASTContext().getSourceManager();
- SourceLocation Location = Manager.getSpellingLoc(Expr->getLocation());
- checkAndAddLocation(Location);
- }
-
- return true;
- }
-
- bool VisitMemberExpr(const MemberExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl().getDecl();
- if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end()) {
- const SourceManager &Manager = Decl->getASTContext().getSourceManager();
- SourceLocation Location = Manager.getSpellingLoc(Expr->getMemberLoc());
- checkAndAddLocation(Location);
- }
- return true;
- }
-
- // Other visitors:
-
- bool VisitTypeLoc(const TypeLoc Loc) {
- if (USRSet.find(getUSRForDecl(Loc.getType()->getAsCXXRecordDecl())) !=
- USRSet.end())
- checkAndAddLocation(Loc.getBeginLoc());
- if (const auto *TemplateTypeParm =
- dyn_cast<TemplateTypeParmType>(Loc.getType())) {
- if (USRSet.find(getUSRForDecl(TemplateTypeParm->getDecl())) !=
- USRSet.end())
- checkAndAddLocation(Loc.getBeginLoc());
+ bool visitSymbolOccurrence(const NamedDecl *ND,
+ ArrayRef<SourceRange> NameRanges) {
+ if (USRSet.find(getUSRForDecl(ND)) != USRSet.end()) {
+ assert(NameRanges.size() == 1 &&
+ "Multiple name pieces are not supported yet!");
+ SourceLocation Loc = NameRanges[0].getBegin();
+ const SourceManager &SM = Context.getSourceManager();
+ // TODO: Deal with macro occurrences correctly.
+ if (Loc.isMacroID())
+ Loc = SM.getSpellingLoc(Loc);
+ checkAndAddLocation(Loc);
}
return true;
}
@@ -116,17 +74,6 @@ public:
return LocationsFound;
}
- // Namespace traversal:
- void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
- while (NameLoc) {
- const NamespaceDecl *Decl =
- NameLoc.getNestedNameSpecifier()->getAsNamespace();
- if (Decl && USRSet.find(getUSRForDecl(Decl)) != USRSet.end())
- checkAndAddLocation(NameLoc.getLocalBeginLoc());
- NameLoc = NameLoc.getPrefix();
- }
- }
-
private:
void checkAndAddLocation(SourceLocation Loc) {
const SourceLocation BeginLoc = Loc;
@@ -449,11 +396,6 @@ getLocationsOfUSRs(const std::vector<std::string> &USRs, StringRef PrevName,
Decl *Decl) {
USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
Visitor.TraverseDecl(Decl);
- NestedNameSpecifierLocFinder Finder(Decl->getASTContext());
-
- for (const auto &Location : Finder.getNestedNameSpecifierLocations())
- Visitor.handleNestedNameSpecifierLoc(Location);
-
return Visitor.getLocationsFound();
}
OpenPOWER on IntegriCloud