1 //===-- PopulateSwitchTest.cpp ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "TweakTesting.h"
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
17 TWEAK_TEST(PopulateSwitch
);
19 TEST_F(PopulateSwitchTest
, Test
) {
22 llvm::StringRef TestSource
;
23 llvm::StringRef ExpectedSource
;
24 llvm::StringRef FileName
= "TestTU.cpp";
31 R
""(enum Enum
{}; ^switch ((Enum
)0) {})"",
35 // All enumerators already in switch (unscoped)
37 R
""(enum Enum
{A
,B
}; ^switch (A
) {case A
:break;case B
:break;})"",
41 // All enumerators already in switch (scoped)
44 enum class Enum
{A
,B
};
45 ^switch (Enum::A
) {case Enum::A
:break;case Enum::B
:break;}
50 // Default case in switch
53 enum class Enum
{A
,B
};
54 ^switch (Enum::A
) {default:break;}
59 // GNU range in switch
62 enum class Enum
{A
,B
};
63 ^switch (Enum::A
) {case Enum::A
... Enum::B
:break;}
68 // Value dependent case expression
71 enum class Enum
{A
,B
};
74 ^switch (Enum::A
) {case Value
:break;}
80 // Body not CompoundStmt
82 R
""(enum Enum
{A
}; ^switch (A
);)"",
86 // Selection on switch token
88 R
""(enum Enum
{A
}; ^switch (A
) {})"",
89 R
""(enum Enum
{A
}; switch (A
) {case A
:break;})"",
92 // Selection on switch condition
94 R
""(enum Enum
{A
}; switch (^A
) {})"",
95 R
""(enum Enum
{A
}; switch (A
) {case A
:break;})"",
98 // Selection of whole switch condition
100 R
""(enum Enum
{A
}; switch ([[A
]]) {})"",
101 R
""(enum Enum
{A
}; switch (A
) {case A
:break;})"",
104 // Selection in switch body
106 R
""(enum Enum
{A
}; switch (A
) {^})"",
107 R
""(enum Enum
{A
}; switch (A
) {case A
:break;})"",
110 // Scoped enumeration
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
119 enum class Enum
{A
,B
};
123 enum class Enum
{A
,B
};
124 switch (Enum::A
) {case Enum::A
:case Enum::B
:break;}
128 // Only filling in missing enumerators (unscoped)
132 ^switch (A
) {case B
:break;}
136 switch (A
) {case B
:break;case A
:case C
:break;}
140 // Only filling in missing enumerators,
141 // even when using integer literals
145 ^switch (A
) {case 1:break;}
149 switch (A
) {case 1:break;case A
:case C
:break;}
153 // Only filling in missing enumerators (scoped)
156 enum class Enum
{A
,B
,C
};
158 {case Enum::B
:break;}
161 enum class Enum
{A
,B
,C
};
163 {case Enum::B
:break;case Enum::A
:case Enum::C
:break;}
167 // Scoped enumerations in namespace
170 namespace ns
{ enum class Enum
{A
}; }
171 void function() { ^switch (ns::Enum::A
) {} }
174 namespace ns
{ enum class Enum
{A
}; }
175 void function() { switch (ns::Enum::A
) {case ns::Enum::A
:break;} }
179 // Unscoped enumerations in namespace
182 namespace ns
{ enum Enum
{A
}; }
183 void function() { ^switch (ns::A
) {} }
186 namespace ns
{ enum Enum
{A
}; }
187 void function() { switch (ns::A
) {case ns::A
:break;} }
191 // Duplicated constant names
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
199 R
""(enum Enum
{A
,B
,b
=B
}; ^switch (A
) {case A
:case B
:break;})"",
203 // Enum is dependent type
205 R
""(template<typename T
> void f() {enum Enum
{A
}; ^switch (A
) {}})"",
208 {// C: Only filling in missing enumerators
213 ^switch (val
) {case B
:break;}
218 switch (val
) {case B
:break;case A
:case C
:break;}
221 {// C: Only filling in missing enumerators w/ typedefs
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;}
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;}
242 for (const auto &Case
: Cases
) {
243 Context
= Case
.Context
;
244 FileName
= Case
.FileName
;
245 EXPECT_EQ(apply(Case
.TestSource
), Case
.ExpectedSource
);
250 } // namespace clangd