Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / Rename / RenameMemberTest.cpp
blobc16d16aa25f047094943f2970b77c1dcce5bb628
1 //===-- ClangMemberTests.cpp - unit tests for renaming class members ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "ClangRenameTest.h"
11 namespace clang {
12 namespace clang_rename {
13 namespace test {
14 namespace {
16 class RenameMemberTest : public ClangRenameTest {
17 public:
18 RenameMemberTest() {
19 AppendToHeader(R"(
20 struct NA {
21 void Foo();
22 void NotFoo();
23 static void SFoo();
24 static void SNotFoo();
25 int Moo;
27 struct A {
28 virtual void Foo();
29 void NotFoo();
30 static void SFoo();
31 static void SNotFoo();
32 int Moo;
33 int NotMoo;
34 static int SMoo;
36 struct B : public A {
37 void Foo() override;
39 template <typename T> struct TA {
40 T* Foo();
41 T* NotFoo();
42 static T* SFoo();
43 static T* NotSFoo();
45 template <typename T> struct TB : public TA<T> {};
46 namespace ns {
47 template <typename T> struct TA {
48 T* Foo();
49 T* NotFoo();
50 static T* SFoo();
51 static T* NotSFoo();
52 static int SMoo;
54 template <typename T> struct TB : public TA<T> {};
55 struct A {
56 void Foo();
57 void NotFoo();
58 static void SFoo();
59 static void SNotFoo();
61 struct B : public A {};
62 struct C {
63 template <class T>
64 void SFoo(const T& t) {}
65 template <class T>
66 void Foo() {}
68 })");
72 INSTANTIATE_TEST_SUITE_P(
73 DISABLED_RenameTemplatedClassStaticVariableTest, RenameMemberTest,
74 testing::ValuesIn(std::vector<Case>({
75 // FIXME: support renaming static variables for template classes.
76 {"void f() { ns::TA<int>::SMoo; }",
77 "void f() { ns::TA<int>::SMeh; }", "ns::TA::SMoo", "ns::TA::SMeh"},
78 })) );
80 INSTANTIATE_TEST_SUITE_P(
81 RenameMemberTest, RenameMemberTest,
82 testing::ValuesIn(std::vector<Case>({
83 // Normal methods and fields.
84 {"void f() { A a; a.Foo(); }", "void f() { A a; a.Bar(); }", "A::Foo",
85 "A::Bar"},
86 {"void f() { ns::A a; a.Foo(); }", "void f() { ns::A a; a.Bar(); }",
87 "ns::A::Foo", "ns::A::Bar"},
88 {"void f() { A a; int x = a.Moo; }", "void f() { A a; int x = a.Meh; }",
89 "A::Moo", "A::Meh"},
90 {"void f() { B b; b.Foo(); }", "void f() { B b; b.Bar(); }", "B::Foo",
91 "B::Bar"},
92 {"void f() { ns::B b; b.Foo(); }", "void f() { ns::B b; b.Bar(); }",
93 "ns::A::Foo", "ns::A::Bar"},
94 {"void f() { B b; int x = b.Moo; }", "void f() { B b; int x = b.Meh; }",
95 "A::Moo", "A::Meh"},
97 // Static methods.
98 {"void f() { A::SFoo(); }", "void f() { A::SBar(); }", "A::SFoo",
99 "A::SBar"},
100 {"void f() { ns::A::SFoo(); }", "void f() { ns::A::SBar(); }",
101 "ns::A::SFoo", "ns::A::SBar"},
102 {"void f() { TA<int>::SFoo(); }", "void f() { TA<int>::SBar(); }",
103 "TA::SFoo", "TA::SBar"},
104 {"void f() { ns::TA<int>::SFoo(); }",
105 "void f() { ns::TA<int>::SBar(); }", "ns::TA::SFoo", "ns::TA::SBar"},
107 // Static variables.
108 {"void f() { A::SMoo; }",
109 "void f() { A::SMeh; }", "A::SMoo", "A::SMeh"},
111 // Templated methods.
112 {"void f() { TA<int> a; a.Foo(); }", "void f() { TA<int> a; a.Bar(); }",
113 "TA::Foo", "TA::Bar"},
114 {"void f() { ns::TA<int> a; a.Foo(); }",
115 "void f() { ns::TA<int> a; a.Bar(); }", "ns::TA::Foo", "ns::TA::Bar"},
116 {"void f() { TB<int> b; b.Foo(); }", "void f() { TB<int> b; b.Bar(); }",
117 "TA::Foo", "TA::Bar"},
118 {"void f() { ns::TB<int> b; b.Foo(); }",
119 "void f() { ns::TB<int> b; b.Bar(); }", "ns::TA::Foo", "ns::TA::Bar"},
120 {"void f() { ns::C c; int x; c.SFoo(x); }",
121 "void f() { ns::C c; int x; c.SBar(x); }", "ns::C::SFoo",
122 "ns::C::SBar"},
123 {"void f() { ns::C c; c.Foo<int>(); }",
124 "void f() { ns::C c; c.Bar<int>(); }", "ns::C::Foo", "ns::C::Bar"},
126 // Pointers to methods.
127 {"void f() { auto p = &A::Foo; }", "void f() { auto p = &A::Bar; }",
128 "A::Foo", "A::Bar"},
129 {"void f() { auto p = &A::SFoo; }", "void f() { auto p = &A::SBar; }",
130 "A::SFoo", "A::SBar"},
131 {"void f() { auto p = &B::Foo; }", "void f() { auto p = &B::Bar; }",
132 "B::Foo", "B::Bar"},
133 {"void f() { auto p = &ns::A::Foo; }",
134 "void f() { auto p = &ns::A::Bar; }", "ns::A::Foo", "ns::A::Bar"},
135 {"void f() { auto p = &ns::A::SFoo; }",
136 "void f() { auto p = &ns::A::SBar; }", "ns::A::SFoo", "ns::A::SBar"},
137 {"void f() { auto p = &ns::C::SFoo<int>; }",
138 "void f() { auto p = &ns::C::SBar<int>; }", "ns::C::SFoo",
139 "ns::C::SBar"},
141 // These methods are not declared or overridden in the subclass B, we
142 // have to use the qualified name with parent class A to identify them.
143 {"void f() { auto p = &ns::B::Foo; }",
144 "void f() { auto p = &ns::B::Bar; }", "ns::A::Foo", "ns::B::Bar"},
145 {"void f() { B::SFoo(); }", "void f() { B::SBar(); }", "A::SFoo",
146 "B::SBar"},
147 {"void f() { ns::B::SFoo(); }", "void f() { ns::B::SBar(); }",
148 "ns::A::SFoo", "ns::B::SBar"},
149 {"void f() { auto p = &B::SFoo; }", "void f() { auto p = &B::SBar; }",
150 "A::SFoo", "B::SBar"},
151 {"void f() { auto p = &ns::B::SFoo; }",
152 "void f() { auto p = &ns::B::SBar; }", "ns::A::SFoo", "ns::B::SBar"},
153 {"void f() { TB<int>::SFoo(); }", "void f() { TB<int>::SBar(); }",
154 "TA::SFoo", "TB::SBar"},
155 {"void f() { ns::TB<int>::SFoo(); }",
156 "void f() { ns::TB<int>::SBar(); }", "ns::TA::SFoo", "ns::TB::SBar"},
157 })) );
159 TEST_P(RenameMemberTest, RenameMembers) {
160 auto Param = GetParam();
161 assert(!Param.OldName.empty());
162 assert(!Param.NewName.empty());
163 std::string Actual =
164 runClangRenameOnCode(Param.Before, Param.OldName, Param.NewName);
165 CompareSnippets(Param.After, Actual);
168 TEST_F(RenameMemberTest, RenameMemberInsideClassMethods) {
169 std::string Before = R"(
170 struct X {
171 int Moo;
172 void Baz() { Moo = 1; }
173 };)";
174 std::string Expected = R"(
175 struct X {
176 int Meh;
177 void Baz() { Meh = 1; }
178 };)";
179 std::string After = runClangRenameOnCode(Before, "X::Moo", "Y::Meh");
180 CompareSnippets(Expected, After);
183 TEST_F(RenameMemberTest, RenameMethodInsideClassMethods) {
184 std::string Before = R"(
185 struct X {
186 void Foo() {}
187 void Baz() { Foo(); }
188 };)";
189 std::string Expected = R"(
190 struct X {
191 void Bar() {}
192 void Baz() { Bar(); }
193 };)";
194 std::string After = runClangRenameOnCode(Before, "X::Foo", "X::Bar");
195 CompareSnippets(Expected, After);
198 TEST_F(RenameMemberTest, RenameCtorInitializer) {
199 std::string Before = R"(
200 class X {
201 public:
202 X();
203 A a;
204 A a2;
205 B b;
208 X::X():a(), b() {}
210 std::string Expected = R"(
211 class X {
212 public:
213 X();
214 A bar;
215 A a2;
216 B b;
219 X::X():bar(), b() {}
221 std::string After = runClangRenameOnCode(Before, "X::a", "X::bar");
222 CompareSnippets(Expected, After);
225 } // anonymous namespace
226 } // namespace test
227 } // namespace clang_rename
228 } // namesdpace clang