Skip to content

Commit 84a9ed2

Browse files
authored
[clangd] Preserve qualified names in "override pure virtual methods" tweak (#163726)
Prevents the tweak from splitting **qualified names** (e.g., `foo::Type`) by incorrectly inserting a space around the scope resolution (`::`). **Before:** ```cpp // input: virtual foo::Type::func() = 0 // output: foo :: Type :: func() ``` **After:** ```cpp // input: virtual foo::Type::func() = 0 // output: foo::Type::func() ```
1 parent d65e712 commit 84a9ed2

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

clang-tools-extra/clangd/refactor/tweaks/OverridePureVirtuals.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979

8080
#include "clang/AST/ASTContext.h"
8181
#include "clang/AST/DeclCXX.h"
82-
#include "clang/AST/Type.h"
82+
#include "clang/AST/TypeBase.h"
8383
#include "clang/AST/TypeLoc.h"
8484
#include "clang/Basic/LLVM.h"
8585
#include "clang/Basic/SourceLocation.h"
@@ -116,7 +116,8 @@ std::string removePureVirtualSyntax(const std::string &MethodDecl,
116116

117117
DeclString += Tk.text();
118118
if (Tk.Kind != tok::l_paren && Next.Kind != tok::comma &&
119-
Next.Kind != tok::r_paren && Next.Kind != tok::l_paren)
119+
Next.Kind != tok::r_paren && Next.Kind != tok::l_paren &&
120+
Tk.Kind != tok::coloncolon && Next.Kind != tok::coloncolon)
120121
DeclString += ' ';
121122
}
122123
// Trim the last whitespace.

clang-tools-extra/clangd/unittests/tweaks/OverridePureVirtualsTests.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,45 @@ class D : public B {
715715
EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;
716716
}
717717

718+
TEST_F(OverridePureVirtualsTests, QualifiedNames) {
719+
constexpr auto Before = R"cpp(
720+
namespace foo { struct S{}; namespace bar { struct S2{}; } }
721+
722+
class B {
723+
public:
724+
virtual foo::S foo(int var = 0) = 0;
725+
virtual foo::bar::S2 bar(int var = 0) = 0;
726+
};
727+
728+
class ^D : public B {};
729+
)cpp";
730+
731+
constexpr auto Expected = R"cpp(
732+
namespace foo { struct S{}; namespace bar { struct S2{}; } }
733+
734+
class B {
735+
public:
736+
virtual foo::S foo(int var = 0) = 0;
737+
virtual foo::bar::S2 bar(int var = 0) = 0;
738+
};
739+
740+
class D : public B {
741+
public:
742+
foo::S foo(int var = 0) override {
743+
// TODO: Implement this pure virtual method.
744+
static_assert(false, "Method `foo` is not implemented.");
745+
}
746+
747+
foo::bar::S2 bar(int var = 0) override {
748+
// TODO: Implement this pure virtual method.
749+
static_assert(false, "Method `bar` is not implemented.");
750+
}
751+
};
752+
)cpp";
753+
auto Applied = apply(Before);
754+
EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;
755+
}
756+
718757
} // namespace
719758
} // namespace clangd
720759
} // namespace clang

0 commit comments

Comments
 (0)