xref: /llvm-project/clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp (revision 4d006520b8c0cc3a52913b4665bf741c737e5592)
15934a791SAdam Czachorowski //===-- PopulateSwitchTest.cpp ----------------------------------*- C++ -*-===//
25934a791SAdam Czachorowski //
35934a791SAdam Czachorowski // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45934a791SAdam Czachorowski // See https://llvm.org/LICENSE.txt for license information.
55934a791SAdam Czachorowski // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65934a791SAdam Czachorowski //
75934a791SAdam Czachorowski //===----------------------------------------------------------------------===//
85934a791SAdam Czachorowski 
95934a791SAdam Czachorowski #include "TweakTesting.h"
105934a791SAdam Czachorowski #include "gmock/gmock.h"
115934a791SAdam Czachorowski #include "gtest/gtest.h"
125934a791SAdam Czachorowski 
135934a791SAdam Czachorowski namespace clang {
145934a791SAdam Czachorowski namespace clangd {
155934a791SAdam Czachorowski namespace {
165934a791SAdam Czachorowski 
175934a791SAdam Czachorowski TWEAK_TEST(PopulateSwitch);
185934a791SAdam Czachorowski 
TEST_F(PopulateSwitchTest,Test)195934a791SAdam Czachorowski TEST_F(PopulateSwitchTest, Test) {
205934a791SAdam Czachorowski   struct Case {
215934a791SAdam Czachorowski     CodeContext Context;
225934a791SAdam Czachorowski     llvm::StringRef TestSource;
235934a791SAdam Czachorowski     llvm::StringRef ExpectedSource;
24*a90d57b6SDavid Goldman     llvm::StringRef FileName = "TestTU.cpp";
255934a791SAdam Czachorowski   };
265934a791SAdam Czachorowski 
275934a791SAdam Czachorowski   Case Cases[]{
285934a791SAdam Czachorowski       {
295934a791SAdam Czachorowski           // No enumerators
305934a791SAdam Czachorowski           Function,
315934a791SAdam Czachorowski           R""(enum Enum {}; ^switch ((Enum)0) {})"",
325934a791SAdam Czachorowski           "unavailable",
335934a791SAdam Czachorowski       },
345934a791SAdam Czachorowski       {
355934a791SAdam Czachorowski           // All enumerators already in switch (unscoped)
365934a791SAdam Czachorowski           Function,
375934a791SAdam Czachorowski           R""(enum Enum {A,B}; ^switch (A) {case A:break;case B:break;})"",
385934a791SAdam Czachorowski           "unavailable",
395934a791SAdam Czachorowski       },
405934a791SAdam Czachorowski       {
415934a791SAdam Czachorowski           // All enumerators already in switch (scoped)
425934a791SAdam Czachorowski           Function,
435934a791SAdam Czachorowski           R""(
445934a791SAdam Czachorowski             enum class Enum {A,B};
455934a791SAdam Czachorowski             ^switch (Enum::A) {case Enum::A:break;case Enum::B:break;}
465934a791SAdam Czachorowski           )"",
475934a791SAdam Czachorowski           "unavailable",
485934a791SAdam Czachorowski       },
495934a791SAdam Czachorowski       {
505934a791SAdam Czachorowski           // Default case in switch
515934a791SAdam Czachorowski           Function,
525934a791SAdam Czachorowski           R""(
535934a791SAdam Czachorowski             enum class Enum {A,B};
545934a791SAdam Czachorowski             ^switch (Enum::A) {default:break;}
555934a791SAdam Czachorowski           )"",
565934a791SAdam Czachorowski           "unavailable",
575934a791SAdam Czachorowski       },
585934a791SAdam Czachorowski       {
595934a791SAdam Czachorowski           // GNU range in switch
605934a791SAdam Czachorowski           Function,
615934a791SAdam Czachorowski           R""(
625934a791SAdam Czachorowski             enum class Enum {A,B};
635934a791SAdam Czachorowski             ^switch (Enum::A) {case Enum::A ... Enum::B:break;}
645934a791SAdam Czachorowski           )"",
655934a791SAdam Czachorowski           "unavailable",
665934a791SAdam Czachorowski       },
675934a791SAdam Czachorowski       {
685934a791SAdam Czachorowski           // Value dependent case expression
695934a791SAdam Czachorowski           File,
705934a791SAdam Czachorowski           R""(
715934a791SAdam Czachorowski             enum class Enum {A,B};
725934a791SAdam Czachorowski             template<Enum Value>
735934a791SAdam Czachorowski             void function() {
745934a791SAdam Czachorowski                 ^switch (Enum::A) {case Value:break;}
755934a791SAdam Czachorowski             }
765934a791SAdam Czachorowski           )"",
775934a791SAdam Czachorowski           "unavailable",
785934a791SAdam Czachorowski       },
795934a791SAdam Czachorowski       {
805934a791SAdam Czachorowski           // Body not CompoundStmt
815934a791SAdam Czachorowski           Function,
825934a791SAdam Czachorowski           R""(enum Enum {A}; ^switch (A);)"",
835934a791SAdam Czachorowski           "unavailable",
845934a791SAdam Czachorowski       },
855934a791SAdam Czachorowski       {
865934a791SAdam Czachorowski           // Selection on switch token
875934a791SAdam Czachorowski           Function,
885934a791SAdam Czachorowski           R""(enum Enum {A}; ^switch (A) {})"",
895934a791SAdam Czachorowski           R""(enum Enum {A}; switch (A) {case A:break;})"",
905934a791SAdam Czachorowski       },
915934a791SAdam Czachorowski       {
925934a791SAdam Czachorowski           // Selection on switch condition
935934a791SAdam Czachorowski           Function,
945934a791SAdam Czachorowski           R""(enum Enum {A}; switch (^A) {})"",
955934a791SAdam Czachorowski           R""(enum Enum {A}; switch (A) {case A:break;})"",
965934a791SAdam Czachorowski       },
975934a791SAdam Czachorowski       {
98c5c3cdb9SSam McCall           // Selection of whole switch condition
99c5c3cdb9SSam McCall           Function,
100c5c3cdb9SSam McCall           R""(enum Enum {A}; switch ([[A]]) {})"",
101c5c3cdb9SSam McCall           R""(enum Enum {A}; switch (A) {case A:break;})"",
102c5c3cdb9SSam McCall       },
103c5c3cdb9SSam McCall       {
1045934a791SAdam Czachorowski           // Selection in switch body
1055934a791SAdam Czachorowski           Function,
1065934a791SAdam Czachorowski           R""(enum Enum {A}; switch (A) {^})"",
1075934a791SAdam Czachorowski           R""(enum Enum {A}; switch (A) {case A:break;})"",
1085934a791SAdam Czachorowski       },
1095934a791SAdam Czachorowski       {
1105934a791SAdam Czachorowski           // Scoped enumeration
1115934a791SAdam Czachorowski           Function,
1125934a791SAdam Czachorowski           R""(enum class Enum {A}; ^switch (Enum::A) {})"",
1135934a791SAdam Czachorowski           R""(enum class Enum {A}; switch (Enum::A) {case Enum::A:break;})"",
1145934a791SAdam Czachorowski       },
1155934a791SAdam Czachorowski       {
1165934a791SAdam Czachorowski           // Scoped enumeration with multiple enumerators
1175934a791SAdam Czachorowski           Function,
1185934a791SAdam Czachorowski           R""(
1195934a791SAdam Czachorowski             enum class Enum {A,B};
1205934a791SAdam Czachorowski             ^switch (Enum::A) {}
1215934a791SAdam Czachorowski           )"",
1225934a791SAdam Czachorowski           R""(
1235934a791SAdam Czachorowski             enum class Enum {A,B};
1245934a791SAdam Czachorowski             switch (Enum::A) {case Enum::A:case Enum::B:break;}
1255934a791SAdam Czachorowski           )"",
1265934a791SAdam Czachorowski       },
1275934a791SAdam Czachorowski       {
1285934a791SAdam Czachorowski           // Only filling in missing enumerators (unscoped)
1295934a791SAdam Czachorowski           Function,
1305934a791SAdam Czachorowski           R""(
1315934a791SAdam Czachorowski             enum Enum {A,B,C};
1325934a791SAdam Czachorowski             ^switch (A) {case B:break;}
1335934a791SAdam Czachorowski           )"",
1345934a791SAdam Czachorowski           R""(
1355934a791SAdam Czachorowski             enum Enum {A,B,C};
1365934a791SAdam Czachorowski             switch (A) {case B:break;case A:case C:break;}
1375934a791SAdam Czachorowski           )"",
1385934a791SAdam Czachorowski       },
1395934a791SAdam Czachorowski       {
1405934a791SAdam Czachorowski           // Only filling in missing enumerators,
1415934a791SAdam Czachorowski           // even when using integer literals
1425934a791SAdam Czachorowski           Function,
1435934a791SAdam Czachorowski           R""(
1445934a791SAdam Czachorowski             enum Enum {A,B=1,C};
1455934a791SAdam Czachorowski             ^switch (A) {case 1:break;}
1465934a791SAdam Czachorowski           )"",
1475934a791SAdam Czachorowski           R""(
1485934a791SAdam Czachorowski             enum Enum {A,B=1,C};
1495934a791SAdam Czachorowski             switch (A) {case 1:break;case A:case C:break;}
1505934a791SAdam Czachorowski           )"",
1515934a791SAdam Czachorowski       },
1525934a791SAdam Czachorowski       {
1535934a791SAdam Czachorowski           // Only filling in missing enumerators (scoped)
1545934a791SAdam Czachorowski           Function,
1555934a791SAdam Czachorowski           R""(
1565934a791SAdam Czachorowski             enum class Enum {A,B,C};
1575934a791SAdam Czachorowski             ^switch (Enum::A)
1585934a791SAdam Czachorowski             {case Enum::B:break;}
1595934a791SAdam Czachorowski           )"",
1605934a791SAdam Czachorowski           R""(
1615934a791SAdam Czachorowski             enum class Enum {A,B,C};
1625934a791SAdam Czachorowski             switch (Enum::A)
1635934a791SAdam Czachorowski             {case Enum::B:break;case Enum::A:case Enum::C:break;}
1645934a791SAdam Czachorowski           )"",
1655934a791SAdam Czachorowski       },
1665934a791SAdam Czachorowski       {
1675934a791SAdam Czachorowski           // Scoped enumerations in namespace
1685934a791SAdam Czachorowski           File,
1695934a791SAdam Czachorowski           R""(
1705934a791SAdam Czachorowski             namespace ns { enum class Enum {A}; }
1715934a791SAdam Czachorowski             void function() { ^switch (ns::Enum::A) {} }
1725934a791SAdam Czachorowski           )"",
1735934a791SAdam Czachorowski           R""(
1745934a791SAdam Czachorowski             namespace ns { enum class Enum {A}; }
1755934a791SAdam Czachorowski             void function() { switch (ns::Enum::A) {case ns::Enum::A:break;} }
1765934a791SAdam Czachorowski           )"",
1775934a791SAdam Czachorowski       },
1785934a791SAdam Czachorowski       {
1795934a791SAdam Czachorowski           // Unscoped enumerations in namespace
1805934a791SAdam Czachorowski           File,
1815934a791SAdam Czachorowski           R""(
1825934a791SAdam Czachorowski             namespace ns { enum Enum {A}; }
1835934a791SAdam Czachorowski             void function() { ^switch (ns::A) {} }
1845934a791SAdam Czachorowski           )"",
1855934a791SAdam Czachorowski           R""(
1865934a791SAdam Czachorowski             namespace ns { enum Enum {A}; }
1875934a791SAdam Czachorowski             void function() { switch (ns::A) {case ns::A:break;} }
1885934a791SAdam Czachorowski           )"",
1895934a791SAdam Czachorowski       },
1905934a791SAdam Czachorowski       {
1915934a791SAdam Czachorowski           // Duplicated constant names
1925934a791SAdam Czachorowski           Function,
1935934a791SAdam Czachorowski           R""(enum Enum {A,B,b=B}; ^switch (A) {})"",
1945934a791SAdam Czachorowski           R""(enum Enum {A,B,b=B}; switch (A) {case A:case B:break;})"",
1955934a791SAdam Czachorowski       },
1965934a791SAdam Czachorowski       {
1975934a791SAdam Czachorowski           // Duplicated constant names all in switch
1985934a791SAdam Czachorowski           Function,
1995934a791SAdam Czachorowski           R""(enum Enum {A,B,b=B}; ^switch (A) {case A:case B:break;})"",
2005934a791SAdam Czachorowski           "unavailable",
2015934a791SAdam Czachorowski       },
2025934a791SAdam Czachorowski       {
2035934a791SAdam Czachorowski           // Enum is dependent type
2045934a791SAdam Czachorowski           File,
2055934a791SAdam Czachorowski           R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",
2065934a791SAdam Czachorowski           "unavailable",
2075934a791SAdam Czachorowski       },
208*a90d57b6SDavid Goldman       {// C: Only filling in missing enumerators
209*a90d57b6SDavid Goldman        Function,
210*a90d57b6SDavid Goldman        R""(
211*a90d57b6SDavid Goldman             enum CEnum {A,B,C};
212*a90d57b6SDavid Goldman             enum CEnum val = A;
213*a90d57b6SDavid Goldman             ^switch (val) {case B:break;}
214*a90d57b6SDavid Goldman           )"",
215*a90d57b6SDavid Goldman        R""(
216*a90d57b6SDavid Goldman             enum CEnum {A,B,C};
217*a90d57b6SDavid Goldman             enum CEnum val = A;
218*a90d57b6SDavid Goldman             switch (val) {case B:break;case A:case C:break;}
219*a90d57b6SDavid Goldman           )"",
220*a90d57b6SDavid Goldman        "TestTU.c"},
221*a90d57b6SDavid Goldman       {// C: Only filling in missing enumerators w/ typedefs
222*a90d57b6SDavid Goldman        Function,
223*a90d57b6SDavid Goldman        R""(
224*a90d57b6SDavid Goldman             typedef unsigned long UInteger;
225*a90d57b6SDavid Goldman             enum ControlState : UInteger;
226*a90d57b6SDavid Goldman             typedef enum ControlState ControlState;
227*a90d57b6SDavid Goldman             enum ControlState : UInteger {A,B,C};
228*a90d57b6SDavid Goldman             ControlState controlState = A;
229*a90d57b6SDavid Goldman             switch (^controlState) {case A:break;}
230*a90d57b6SDavid Goldman           )"",
231*a90d57b6SDavid Goldman        R""(
232*a90d57b6SDavid Goldman             typedef unsigned long UInteger;
233*a90d57b6SDavid Goldman             enum ControlState : UInteger;
234*a90d57b6SDavid Goldman             typedef enum ControlState ControlState;
235*a90d57b6SDavid Goldman             enum ControlState : UInteger {A,B,C};
236*a90d57b6SDavid Goldman             ControlState controlState = A;
237*a90d57b6SDavid Goldman             switch (controlState) {case A:break;case B:case C:break;}
238*a90d57b6SDavid Goldman           )"",
239*a90d57b6SDavid Goldman        "TestTU.c"},
2405934a791SAdam Czachorowski   };
2415934a791SAdam Czachorowski 
2425934a791SAdam Czachorowski   for (const auto &Case : Cases) {
2435934a791SAdam Czachorowski     Context = Case.Context;
244*a90d57b6SDavid Goldman     FileName = Case.FileName;
2455934a791SAdam Czachorowski     EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
2465934a791SAdam Czachorowski   }
2475934a791SAdam Czachorowski }
2485934a791SAdam Czachorowski 
2495934a791SAdam Czachorowski } // namespace
2505934a791SAdam Czachorowski } // namespace clangd
2515934a791SAdam Czachorowski } // namespace clang
252