diff --git a/clang-tools-extra/clang-move/ClangMove.cpp b/clang-tools-extra/clang-move/ClangMove.cpp index f20cf1ec4ca2..0f104e499eb8 100644 --- a/clang-tools-extra/clang-move/ClangMove.cpp +++ b/clang-tools-extra/clang-move/ClangMove.cpp @@ -899,21 +899,21 @@ void ClangMoveTool::onEndOfTranslationUnit() { assert(Reporter); for (const auto *Decl : UnremovedDeclsInOldHeader) { auto Kind = Decl->getKind(); + bool Templated = Decl->isTemplated(); const std::string QualifiedName = Decl->getQualifiedNameAsString(); if (Kind == Decl::Kind::Var) - Reporter->reportDeclaration(QualifiedName, "Variable"); + Reporter->reportDeclaration(QualifiedName, "Variable", Templated); else if (Kind == Decl::Kind::Function || Kind == Decl::Kind::FunctionTemplate) - Reporter->reportDeclaration(QualifiedName, "Function"); + Reporter->reportDeclaration(QualifiedName, "Function", Templated); else if (Kind == Decl::Kind::ClassTemplate || Kind == Decl::Kind::CXXRecord) - Reporter->reportDeclaration(QualifiedName, "Class"); + Reporter->reportDeclaration(QualifiedName, "Class", Templated); else if (Kind == Decl::Kind::Enum) - Reporter->reportDeclaration(QualifiedName, "Enum"); - else if (Kind == Decl::Kind::Typedef || - Kind == Decl::Kind::TypeAlias || + Reporter->reportDeclaration(QualifiedName, "Enum", Templated); + else if (Kind == Decl::Kind::Typedef || Kind == Decl::Kind::TypeAlias || Kind == Decl::Kind::TypeAliasTemplate) - Reporter->reportDeclaration(QualifiedName, "TypeAlias"); + Reporter->reportDeclaration(QualifiedName, "TypeAlias", Templated); } return; } diff --git a/clang-tools-extra/clang-move/ClangMove.h b/clang-tools-extra/clang-move/ClangMove.h index 945c6db0aaa9..94172181e93d 100644 --- a/clang-tools-extra/clang-move/ClangMove.h +++ b/clang-tools-extra/clang-move/ClangMove.h @@ -17,6 +17,7 @@ #include "clang/Tooling/Tooling.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include #include #include @@ -31,23 +32,30 @@ public: DeclarationReporter() = default; ~DeclarationReporter() = default; - void reportDeclaration(llvm::StringRef DeclarationName, - llvm::StringRef Type) { - DeclarationList.emplace_back(DeclarationName, Type); + void reportDeclaration(llvm::StringRef DeclarationName, llvm::StringRef Type, + bool Templated) { + DeclarationList.emplace_back(DeclarationName, Type, Templated); }; - // A pair. - // The DeclarationName is a fully qualified name for the declaration, like - // A::B::Foo. The DeclarationKind is a string represents the kind of the - // declaration, currently only "Function" and "Class" are supported. - typedef std::pair DeclarationPair; + struct Declaration { + Declaration(llvm::StringRef QName, llvm::StringRef Kind, bool Templated) + : QualifiedName(QName), Kind(Kind), Templated(Templated) {} - const std::vector getDeclarationList() const { + friend bool operator==(const Declaration &LHS, const Declaration &RHS) { + return std::tie(LHS.QualifiedName, LHS.Kind, LHS.Templated) == + std::tie(RHS.QualifiedName, RHS.Kind, RHS.Templated); + } + std::string QualifiedName; // E.g. A::B::Foo. + std::string Kind; // E.g. Function, Class + bool Templated = false; // Whether the declaration is templated. + }; + + const std::vector getDeclarationList() const { return DeclarationList; } private: - std::vector DeclarationList; + std::vector DeclarationList; }; // Specify declarations being moved. It contains all information of the moved diff --git a/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp b/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp index e5fee263564c..b882b6ec23a7 100644 --- a/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp +++ b/clang-tools-extra/clang-move/tool/ClangMoveMain.cpp @@ -138,8 +138,10 @@ int main(int argc, const char **argv) { const auto &Declarations = Reporter.getDeclarationList(); for (auto I = Declarations.begin(), E = Declarations.end(); I != E; ++I) { llvm::outs() << " {\n"; - llvm::outs() << " \"DeclarationName\": \"" << I->first << "\",\n"; - llvm::outs() << " \"DeclarationType\": \"" << I->second << "\"\n"; + llvm::outs() << " \"DeclarationName\": \"" << I->QualifiedName << "\",\n"; + llvm::outs() << " \"DeclarationType\": \"" << I->Kind << "\"\n"; + llvm::outs() << " \"Templated\": " << (I->Templated ? "true" : "false") + << "\n"; llvm::outs() << " }"; // Don't print trailing "," at the end of last element. if (I != std::prev(E)) diff --git a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp index 45e3f682321f..97c7ce0759d7 100644 --- a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp +++ b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp @@ -16,6 +16,7 @@ #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/StringRef.h" +#include "gmock/gmock-matchers.h" #include "gtest/gtest.h" #include #include @@ -581,7 +582,8 @@ TEST(ClangMove, DumpDecls) { "namespace a {\n" "class Move1 {};\n" "void f1() {}\n" - "void f2();\n" + "template " + "void f2(T t);\n" "} // namespace a\n" "\n" "class ForwardClass;\n" @@ -594,6 +596,8 @@ TEST(ClangMove, DumpDecls) { "typedef int Int2;\n" "typedef A A_d;" "using Int = int;\n" + "template \n" + "using AA = A;\n" "extern int kGlobalInt;\n" "extern const char* const kGlobalStr;\n" "} // namespace b\n" @@ -608,26 +612,28 @@ TEST(ClangMove, DumpDecls) { Spec.NewHeader = "new_foo.h"; Spec.NewCC = "new_foo.cc"; DeclarationReporter Reporter; - std::set ExpectedDeclarations = { - {"A", "Class"}, - {"B", "Class"}, - {"a::Move1", "Class"}, - {"a::f1", "Function"}, - {"a::f2", "Function"}, - {"a::b::Move1", "Class"}, - {"a::b::f", "Function"}, - {"a::b::E1", "Enum"}, - {"a::b::E2", "Enum"}, - {"a::b::Int2", "TypeAlias"}, - {"a::b::A_d", "TypeAlias"}, - {"a::b::Int", "TypeAlias"}, - {"a::b::kGlobalInt", "Variable"}, - {"a::b::kGlobalStr", "Variable"}}; + std::vector ExpectedDeclarations = { + {"A", "Class", true}, + {"B", "Class", false}, + {"a::Move1", "Class", false}, + {"a::f1", "Function", false}, + {"a::f2", "Function", true}, + {"a::b::Move1", "Class", false}, + {"a::b::f", "Function", false}, + {"a::b::E1", "Enum", false}, + {"a::b::E2", "Enum", false}, + {"a::b::Int2", "TypeAlias", false}, + {"a::b::A_d", "TypeAlias", false}, + {"a::b::Int", "TypeAlias", false}, + {"a::b::AA", "TypeAlias", true}, + {"a::b::kGlobalInt", "Variable", false}, + {"a::b::kGlobalStr", "Variable", false}}; runClangMoveOnCode(Spec, TestHeader, TestCode, &Reporter); - std::set Results; - for (const auto& DelPair : Reporter.getDeclarationList()) - Results.insert(DelPair); - EXPECT_EQ(ExpectedDeclarations, Results); + std::vector Results; + for (const auto &DelPair : Reporter.getDeclarationList()) + Results.push_back(DelPair); + EXPECT_THAT(ExpectedDeclarations, + testing::UnorderedElementsAreArray(Results)); } } // namespace