From: Eric Liu Date: Wed, 5 Oct 2016 15:52:39 +0000 (+0000) Subject: [change-namespace] Fixed a bug in getShortestQualifiedNameInNamespace. X-Git-Tag: llvmorg-4.0.0-rc1~8036 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=447164dea22a9a56f1ea45511acc0a040551e767;p=platform%2Fupstream%2Fllvm.git [change-namespace] Fixed a bug in getShortestQualifiedNameInNamespace. Reviewers: hokein Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D25065 llvm-svn: 283333 --- diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.cpp b/clang-tools-extra/change-namespace/ChangeNamespace.cpp index 15ce4ed..6943afd 100644 --- a/clang-tools-extra/change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/change-namespace/ChangeNamespace.cpp @@ -173,21 +173,24 @@ tooling::Replacement createInsertion(SourceLocation Loc, // Returns the shortest qualified name for declaration `DeclName` in the // namespace `NsName`. For example, if `DeclName` is "a::b::X" and `NsName` // is "a::c::d", then "b::X" will be returned. +// \param DeclName A fully qualified name, "::a::b::X" or "a::b::X". +// \param NsName A fully qualified name, "::a::b" or "a::b". Global namespace +// will have empty name. std::string getShortestQualifiedNameInNamespace(llvm::StringRef DeclName, llvm::StringRef NsName) { - llvm::SmallVector DeclNameSplitted; - DeclName.split(DeclNameSplitted, "::"); - if (DeclNameSplitted.size() == 1) - return DeclName; - const auto UnqualifiedName = DeclNameSplitted.back(); - while (true) { + DeclName = DeclName.ltrim(':'); + NsName = NsName.ltrim(':'); + // If `DeclName` is a global variable, we prepend "::" to it if it is not in + // the global namespace. + if (DeclName.find(':') == llvm::StringRef::npos) + return NsName.empty() ? DeclName.str() : ("::" + DeclName).str(); + + while (!DeclName.consume_front((NsName + "::").str())) { const auto Pos = NsName.find_last_of(':'); if (Pos == llvm::StringRef::npos) return DeclName; - const auto Prefix = NsName.substr(0, Pos - 1); - if (DeclName.startswith(Prefix)) - return (Prefix + "::" + UnqualifiedName).str(); - NsName = Prefix; + assert(Pos > 0); + NsName = NsName.substr(0, Pos - 1); } return DeclName; } diff --git a/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp b/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp index 04252d5..e8fdfaf 100644 --- a/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp +++ b/clang-tools-extra/unittests/change-namespace/ChangeNamespaceTests.cpp @@ -113,6 +113,24 @@ TEST_F(ChangeNamespaceTest, SimpleMoveIntoAnotherNestedNamespace) { EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) { + NewNamespace = "na::nc"; + std::string Code = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "class X { A a; };\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "\n" + "namespace nc {\n" + "class X { A a; };\n" + "} // namespace nc\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) { NewNamespace = "na::x::y"; std::string Code = "namespace na {\n"