summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-rename/USRFinder.cpp5
-rw-r--r--clang-tools-extra/clang-rename/USRFindingAction.cpp89
-rw-r--r--clang-tools-extra/test/clang-rename/ComplexFunctionOverride.cpp23
-rw-r--r--clang-tools-extra/test/clang-rename/TemplateClassInstantiation.cpp (renamed from clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByDeclaration.cpp)24
-rw-r--r--clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByTypeUse.cpp44
5 files changed, 100 insertions, 85 deletions
diff --git a/clang-tools-extra/clang-rename/USRFinder.cpp b/clang-tools-extra/clang-rename/USRFinder.cpp
index 2589be18df0..dff0bb9aef5 100644
--- a/clang-tools-extra/clang-rename/USRFinder.cpp
+++ b/clang-tools-extra/clang-rename/USRFinder.cpp
@@ -81,6 +81,11 @@ public:
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);
}
diff --git a/clang-tools-extra/clang-rename/USRFindingAction.cpp b/clang-tools-extra/clang-rename/USRFindingAction.cpp
index e020385ead3..9ceb1aaddde 100644
--- a/clang-tools-extra/clang-rename/USRFindingAction.cpp
+++ b/clang-tools-extra/clang-rename/USRFindingAction.cpp
@@ -20,7 +20,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
@@ -36,7 +35,6 @@
using namespace llvm;
-using namespace clang::ast_matchers;
namespace clang {
namespace rename {
@@ -46,45 +44,66 @@ namespace {
// AdditionalUSRFinder. AdditionalUSRFinder adds USRs of ctor and dtor if given
// Decl refers to class and adds USRs of all overridden methods if Decl refers
// to virtual method.
-class AdditionalUSRFinder : public MatchFinder::MatchCallback {
+class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
public:
explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context,
std::vector<std::string> *USRs)
- : FoundDecl(FoundDecl), Context(Context), USRs(USRs), USRSet(), Finder() {}
+ : FoundDecl(FoundDecl), Context(Context), USRs(USRs) {}
void Find() {
- USRSet.insert(getUSRForDecl(FoundDecl));
+ // Fill OverriddenMethods and PartialSpecs storages.
+ TraverseDecl(Context.getTranslationUnitDecl());
if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
- addUSRsFromOverrideSets(MethodDecl);
- }
- if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
- addUSRsOfCtorDtors(RecordDecl);
+ addUSRsOfOverridenFunctions(MethodDecl);
+ for (const auto &OverriddenMethod : OverriddenMethods) {
+ if (checkIfOverriddenFunctionAscends(OverriddenMethod)) {
+ USRSet.insert(getUSRForDecl(OverriddenMethod));
+ }
+ }
+ } else if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
+ handleCXXRecordDecl(RecordDecl);
+ } else if (const auto *TemplateDecl =
+ dyn_cast<ClassTemplateDecl>(FoundDecl)) {
+ handleClassTemplateDecl(TemplateDecl);
+ } else {
+ USRSet.insert(getUSRForDecl(FoundDecl));
}
- addMatchers();
- Finder.matchAST(Context);
USRs->insert(USRs->end(), USRSet.begin(), USRSet.end());
}
+ bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
+ if (MethodDecl->isVirtual()) {
+ OverriddenMethods.push_back(MethodDecl);
+ }
+ return true;
+ }
+
+ bool VisitClassTemplatePartialSpecializationDecl(
+ const ClassTemplatePartialSpecializationDecl *PartialSpec) {
+ PartialSpecs.push_back(PartialSpec);
+ return true;
+ }
+
private:
- void addMatchers() {
- const auto CXXMethodDeclMatcher =
- cxxMethodDecl(forEachOverridden(cxxMethodDecl().bind("cxxMethodDecl")));
- Finder.addMatcher(CXXMethodDeclMatcher, this);
+ void handleCXXRecordDecl(const CXXRecordDecl *RecordDecl) {
+ RecordDecl = RecordDecl->getDefinition();
+ if (const auto *ClassTemplateSpecDecl
+ = dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl)) {
+ handleClassTemplateDecl(ClassTemplateSpecDecl->getSpecializedTemplate());
+ }
+ addUSRsOfCtorDtors(RecordDecl);
}
- // FIXME: Implement matchesUSR matchers to make lookups more efficient.
- virtual void run(const MatchFinder::MatchResult &Result) {
- const auto *VirtualMethod =
- Result.Nodes.getNodeAs<CXXMethodDecl>("cxxMethodDecl");
- bool Found = false;
- for (const auto &OverriddenMethod : VirtualMethod->overridden_methods()) {
- if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end()) {
- Found = true;
- }
+ void handleClassTemplateDecl(const ClassTemplateDecl *TemplateDecl) {
+ for (const auto *Specialization : TemplateDecl->specializations()) {
+ addUSRsOfCtorDtors(Specialization);
}
- if (Found) {
- USRSet.insert(getUSRForDecl(VirtualMethod));
+ for (const auto *PartialSpec : PartialSpecs) {
+ if (PartialSpec->getSpecializedTemplate() == TemplateDecl) {
+ addUSRsOfCtorDtors(PartialSpec);
+ }
}
+ addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl());
}
void addUSRsOfCtorDtors(const CXXRecordDecl *RecordDecl) {
@@ -93,21 +112,33 @@ private:
USRSet.insert(getUSRForDecl(CtorDecl));
}
USRSet.insert(getUSRForDecl(RecordDecl->getDestructor()));
+ USRSet.insert(getUSRForDecl(RecordDecl));
}
- void addUSRsFromOverrideSets(const CXXMethodDecl *MethodDecl) {
+ void addUSRsOfOverridenFunctions(const CXXMethodDecl *MethodDecl) {
USRSet.insert(getUSRForDecl(MethodDecl));
for (auto &OverriddenMethod : MethodDecl->overridden_methods()) {
// Recursively visit each OverridenMethod.
- addUSRsFromOverrideSets(OverriddenMethod);
+ addUSRsOfOverridenFunctions(OverriddenMethod);
+ }
+ }
+
+ bool checkIfOverriddenFunctionAscends(const CXXMethodDecl *MethodDecl) {
+ for (auto &OverriddenMethod : MethodDecl->overridden_methods()) {
+ if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end()) {
+ return true;
+ }
+ return checkIfOverriddenFunctionAscends(OverriddenMethod);
}
+ return false;
}
const Decl *FoundDecl;
ASTContext &Context;
std::vector<std::string> *USRs;
std::set<std::string> USRSet;
- MatchFinder Finder;
+ std::vector<const CXXMethodDecl*> OverriddenMethods;
+ std::vector<const ClassTemplatePartialSpecializationDecl*> PartialSpecs;
};
} // namespace
diff --git a/clang-tools-extra/test/clang-rename/ComplexFunctionOverride.cpp b/clang-tools-extra/test/clang-rename/ComplexFunctionOverride.cpp
new file mode 100644
index 00000000000..4994e89c34e
--- /dev/null
+++ b/clang-tools-extra/test/clang-rename/ComplexFunctionOverride.cpp
@@ -0,0 +1,23 @@
+// RUN: cat %s > %t.cpp
+// RUN: clang-rename -offset=307 -new-name=bar %t.cpp -i -- -std=c++11
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
+
+struct A {
+ virtual void foo(); // CHECK: virtual void bar();
+};
+
+struct B : A {
+ void foo() override; // CHECK: void bar() override;
+};
+
+struct C : B {
+ void foo() override; // CHECK: void bar() override;
+};
+
+struct D : B {
+ void foo() override; // CHECK: void bar() override;
+};
+
+struct E : D {
+ void foo() override; // CHECK: void bar() override;
+};
diff --git a/clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByDeclaration.cpp b/clang-tools-extra/test/clang-rename/TemplateClassInstantiation.cpp
index 0775e03fa48..453db5dd395 100644
--- a/clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByDeclaration.cpp
+++ b/clang-tools-extra/test/clang-rename/TemplateClassInstantiation.cpp
@@ -1,14 +1,5 @@
-// RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=287 -new-name=Bar %t.cpp -i --
-// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
-
-// Currently unsupported test.
-// FIXME: clang-rename should be able to rename classes with templates
-// correctly.
-// XFAIL: *
-
template <typename T>
-class Foo { // CHECK: class Bar;
+class Foo { // CHECK: class Bar {
public:
T foo(T arg, T& ref, T* ptr) {
T value;
@@ -40,5 +31,14 @@ int main() {
return 0;
}
-// Use grep -FUbo 'C' <file> to get the correct offset of foo when changing
-// this file.
+// RUN: cat %s > %t-0.cpp
+// RUN: clang-rename -offset=29 -new-name=Bar %t-0.cpp -i -- -fno-delayed-template-parsing
+// RUN: sed 's,//.*,,' %t-0.cpp | FileCheck %s
+
+// RUN: cat %s > %t-1.cpp
+// RUN: clang-rename -offset=311 -new-name=Bar %t-1.cpp -i -- -fno-delayed-template-parsing
+// RUN: sed 's,//.*,,' %t-1.cpp | FileCheck %s
+
+// RUN: cat %s > %t-2.cpp
+// RUN: clang-rename -offset=445 -new-name=Bar %t-2.cpp -i -- -fno-delayed-template-parsing
+// RUN: sed 's,//.*,,' %t-2.cpp | FileCheck %s
diff --git a/clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByTypeUse.cpp b/clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByTypeUse.cpp
deleted file mode 100644
index 08f738af750..00000000000
--- a/clang-tools-extra/test/clang-rename/TemplateClassInstantiationFindByTypeUse.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=703 -new-name=Bar %t.cpp -i --
-// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
-
-// Currently unsupported test.
-// FIXME: clang-rename should be able to rename classes with templates
-// correctly.
-// XFAIL: *
-
-template <typename T>
-class Foo { // CHECK: class Bar;
-public:
- T foo(T arg, T& ref, T* ptr) {
- T value;
- int number = 42;
- value = (T)number;
- value = static_cast<T>(number);
- return value;
- }
- static void foo(T value) {}
- T member;
-};
-
-template <typename T>
-void func() {
- Foo<T> obj; // CHECK: Bar<T> obj;
- obj.member = T();
- Foo<T>::foo(); // CHECK: Bar<T>::foo();
-}
-
-int main() {
- Foo<int> i; // CHECK: Bar<int> i;
- i.member = 0;
- Foo<int>::foo(0); // CHECK: Bar<int>::foo(0);
-
- Foo<bool> b; // CHECK: Bar<bool> b;
- b.member = false;
- Foo<bool>::foo(false); // CHECK: Bar<bool>::foo(false);
-
- return 0;
-}
-
-// Use grep -FUbo 'Foo' <file> to get the correct offset of foo when changing
-// this file.
OpenPOWER on IntegriCloud