clang-tools 19.0.0git
PopulateSwitchTests.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
8
9#include "TweakTesting.h"
10#include "gmock/gmock.h"
11#include "gtest/gtest.h"
12
13namespace clang {
14namespace clangd {
15namespace {
16
17TWEAK_TEST(PopulateSwitch);
18
19TEST_F(PopulateSwitchTest, Test) {
20 struct Case {
21 CodeContext Context;
22 llvm::StringRef TestSource;
23 llvm::StringRef ExpectedSource;
24 llvm::StringRef FileName = "TestTU.cpp";
25 };
26
27 Case Cases[]{
28 {
29 // No enumerators
31 R""(enum Enum {}; ^switch ((Enum)0) {})"",
32 "unavailable",
33 },
34 {
35 // All enumerators already in switch (unscoped)
37 R""(enum Enum {A,B}; ^switch (A) {case A:break;case B:break;})"",
38 "unavailable",
39 },
40 {
41 // All enumerators already in switch (scoped)
43 R""(
44 enum class Enum {A,B};
45 ^switch (Enum::A) {case Enum::A:break;case Enum::B:break;}
46 )"",
47 "unavailable",
48 },
49 {
50 // Default case in switch
52 R""(
53 enum class Enum {A,B};
54 ^switch (Enum::A) {default:break;}
55 )"",
56 "unavailable",
57 },
58 {
59 // GNU range in switch
61 R""(
62 enum class Enum {A,B};
63 ^switch (Enum::A) {case Enum::A ... Enum::B:break;}
64 )"",
65 "unavailable",
66 },
67 {
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;}
75 }
76 )"",
77 "unavailable",
78 },
79 {
80 // Body not CompoundStmt
82 R""(enum Enum {A}; ^switch (A);)"",
83 "unavailable",
84 },
85 {
86 // Selection on switch token
88 R""(enum Enum {A}; ^switch (A) {})"",
89 R""(enum Enum {A}; switch (A) {case A:break;})"",
90 },
91 {
92 // Selection on switch condition
94 R""(enum Enum {A}; switch (^A) {})"",
95 R""(enum Enum {A}; switch (A) {case A:break;})"",
96 },
97 {
98 // Selection of whole switch condition
100 R""(enum Enum {A}; switch ([[A]]) {})"",
101 R""(enum Enum {A}; switch (A) {case A:break;})"",
102 },
103 {
104 // Selection in switch body
105 Function,
106 R""(enum Enum {A}; switch (A) {^})"",
107 R""(enum Enum {A}; switch (A) {case A:break;})"",
108 },
109 {
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;})"",
114 },
115 {
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 )"",
126 },
127 {
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 )"",
138 },
139 {
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 )"",
151 },
152 {
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 )"",
165 },
166 {
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 )"",
177 },
178 {
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 )"",
189 },
190 {
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;})"",
195 },
196 {
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",
201 },
202 {
203 // Enum is dependent type
204 File,
205 R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",
206 "unavailable",
207 },
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"},
240 };
241
242 for (const auto &Case : Cases) {
243 Context = Case.Context;
244 FileName = Case.FileName;
245 EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
246 }
247}
248
249} // namespace
250} // namespace clangd
251} // namespace clang
StringRef FileName
#define TWEAK_TEST(TweakID)
Definition: TweakTesting.h:107
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//