Bump version to 19.1.0git
[llvm-project.git] / clang-tools-extra / clangd / unittests / tweaks / PopulateSwitchTests.cpp
blobe043cc80c198c2ed0790bc34fafd4a8247a3b919
1 //===-- PopulateSwitchTest.cpp ----------------------------------*- C++ -*-===//
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 "TweakTesting.h"
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
13 namespace clang {
14 namespace clangd {
15 namespace {
17 TWEAK_TEST(PopulateSwitch);
19 TEST_F(PopulateSwitchTest, Test) {
20 struct Case {
21 CodeContext Context;
22 llvm::StringRef TestSource;
23 llvm::StringRef ExpectedSource;
24 llvm::StringRef FileName = "TestTU.cpp";
27 Case Cases[]{
29 // No enumerators
30 Function,
31 R""(enum Enum {}; ^switch ((Enum)0) {})"",
32 "unavailable",
35 // All enumerators already in switch (unscoped)
36 Function,
37 R""(enum Enum {A,B}; ^switch (A) {case A:break;case B:break;})"",
38 "unavailable",
41 // All enumerators already in switch (scoped)
42 Function,
43 R""(
44 enum class Enum {A,B};
45 ^switch (Enum::A) {case Enum::A:break;case Enum::B:break;}
46 )"",
47 "unavailable",
50 // Default case in switch
51 Function,
52 R""(
53 enum class Enum {A,B};
54 ^switch (Enum::A) {default:break;}
55 )"",
56 "unavailable",
59 // GNU range in switch
60 Function,
61 R""(
62 enum class Enum {A,B};
63 ^switch (Enum::A) {case Enum::A ... Enum::B:break;}
64 )"",
65 "unavailable",
68 // Value dependent case expression
69 File,
70 R""(
71 enum class Enum {A,B};
72 template<Enum Value>
73 void function() {
74 ^switch (Enum::A) {case Value:break;}
76 )"",
77 "unavailable",
80 // Body not CompoundStmt
81 Function,
82 R""(enum Enum {A}; ^switch (A);)"",
83 "unavailable",
86 // Selection on switch token
87 Function,
88 R""(enum Enum {A}; ^switch (A) {})"",
89 R""(enum Enum {A}; switch (A) {case A:break;})"",
92 // Selection on switch condition
93 Function,
94 R""(enum Enum {A}; switch (^A) {})"",
95 R""(enum Enum {A}; switch (A) {case A:break;})"",
98 // Selection of whole switch condition
99 Function,
100 R""(enum Enum {A}; switch ([[A]]) {})"",
101 R""(enum Enum {A}; switch (A) {case A:break;})"",
104 // Selection in switch body
105 Function,
106 R""(enum Enum {A}; switch (A) {^})"",
107 R""(enum Enum {A}; switch (A) {case A:break;})"",
110 // Scoped enumeration
111 Function,
112 R""(enum class Enum {A}; ^switch (Enum::A) {})"",
113 R""(enum class Enum {A}; switch (Enum::A) {case Enum::A:break;})"",
116 // Scoped enumeration with multiple enumerators
117 Function,
118 R""(
119 enum class Enum {A,B};
120 ^switch (Enum::A) {}
121 )"",
122 R""(
123 enum class Enum {A,B};
124 switch (Enum::A) {case Enum::A:case Enum::B:break;}
125 )"",
128 // Only filling in missing enumerators (unscoped)
129 Function,
130 R""(
131 enum Enum {A,B,C};
132 ^switch (A) {case B:break;}
133 )"",
134 R""(
135 enum Enum {A,B,C};
136 switch (A) {case B:break;case A:case C:break;}
137 )"",
140 // Only filling in missing enumerators,
141 // even when using integer literals
142 Function,
143 R""(
144 enum Enum {A,B=1,C};
145 ^switch (A) {case 1:break;}
146 )"",
147 R""(
148 enum Enum {A,B=1,C};
149 switch (A) {case 1:break;case A:case C:break;}
150 )"",
153 // Only filling in missing enumerators (scoped)
154 Function,
155 R""(
156 enum class Enum {A,B,C};
157 ^switch (Enum::A)
158 {case Enum::B:break;}
159 )"",
160 R""(
161 enum class Enum {A,B,C};
162 switch (Enum::A)
163 {case Enum::B:break;case Enum::A:case Enum::C:break;}
164 )"",
167 // Scoped enumerations in namespace
168 File,
169 R""(
170 namespace ns { enum class Enum {A}; }
171 void function() { ^switch (ns::Enum::A) {} }
172 )"",
173 R""(
174 namespace ns { enum class Enum {A}; }
175 void function() { switch (ns::Enum::A) {case ns::Enum::A:break;} }
176 )"",
179 // Unscoped enumerations in namespace
180 File,
181 R""(
182 namespace ns { enum Enum {A}; }
183 void function() { ^switch (ns::A) {} }
184 )"",
185 R""(
186 namespace ns { enum Enum {A}; }
187 void function() { switch (ns::A) {case ns::A:break;} }
188 )"",
191 // Duplicated constant names
192 Function,
193 R""(enum Enum {A,B,b=B}; ^switch (A) {})"",
194 R""(enum Enum {A,B,b=B}; switch (A) {case A:case B:break;})"",
197 // Duplicated constant names all in switch
198 Function,
199 R""(enum Enum {A,B,b=B}; ^switch (A) {case A:case B:break;})"",
200 "unavailable",
203 // Enum is dependent type
204 File,
205 R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",
206 "unavailable",
208 {// C: Only filling in missing enumerators
209 Function,
210 R""(
211 enum CEnum {A,B,C};
212 enum CEnum val = A;
213 ^switch (val) {case B:break;}
214 )"",
215 R""(
216 enum CEnum {A,B,C};
217 enum CEnum val = A;
218 switch (val) {case B:break;case A:case C:break;}
219 )"",
220 "TestTU.c"},
221 {// C: Only filling in missing enumerators w/ typedefs
222 Function,
223 R""(
224 typedef unsigned long UInteger;
225 enum ControlState : UInteger;
226 typedef enum ControlState ControlState;
227 enum ControlState : UInteger {A,B,C};
228 ControlState controlState = A;
229 switch (^controlState) {case A:break;}
230 )"",
231 R""(
232 typedef unsigned long UInteger;
233 enum ControlState : UInteger;
234 typedef enum ControlState ControlState;
235 enum ControlState : UInteger {A,B,C};
236 ControlState controlState = A;
237 switch (controlState) {case A:break;case B:case C:break;}
238 )"",
239 "TestTU.c"},
242 for (const auto &Case : Cases) {
243 Context = Case.Context;
244 FileName = Case.FileName;
245 EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
249 } // namespace
250 } // namespace clangd
251 } // namespace clang