This revision was automatically updated to reflect the committed changes.
Closed by commit rGa90d57b6cc5f: [clangd] Improve PopulateSwitch tweak
(authored by dgoldman).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D110954/new/
https://reviews.llvm.org/D110954
Files:
clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
Index: clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
+++ clang-tools-extra/clangd/unittests/tweaks/PopulateSwitchTests.cpp
@@ -23,6 +23,7 @@
CodeContext Context;
llvm::StringRef TestSource;
llvm::StringRef ExpectedSource;
+ llvm::StringRef FileName = "TestTU.cpp";
};
Case Cases[]{
@@ -206,10 +207,43 @@
R""(template<typename T> void f() {enum Enum {A}; ^switch (A) {}})"",
"unavailable",
},
+ {// C: Only filling in missing enumerators
+ Function,
+ R""(
+ enum CEnum {A,B,C};
+ enum CEnum val = A;
+ ^switch (val) {case B:break;}
+ )"",
+ R""(
+ enum CEnum {A,B,C};
+ enum CEnum val = A;
+ switch (val) {case B:break;case A:case C:break;}
+ )"",
+ "TestTU.c"},
+ {// C: Only filling in missing enumerators w/ typedefs
+ Function,
+ R""(
+ typedef unsigned long UInteger;
+ enum ControlState : UInteger;
+ typedef enum ControlState ControlState;
+ enum ControlState : UInteger {A,B,C};
+ ControlState controlState = A;
+ switch (^controlState) {case A:break;}
+ )"",
+ R""(
+ typedef unsigned long UInteger;
+ enum ControlState : UInteger;
+ typedef enum ControlState ControlState;
+ enum ControlState : UInteger {A,B,C};
+ ControlState controlState = A;
+ switch (controlState) {case A:break;case B:case C:break;}
+ )"",
+ "TestTU.c"},
};
for (const auto &Case : Cases) {
Context = Case.Context;
+ FileName = Case.FileName;
EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
}
}
Index: clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
===================================================================
--- clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
@@ -113,7 +113,8 @@
return false;
// Ignore implicit casts, since enums implicitly cast to integer types.
Cond = Cond->IgnoreParenImpCasts();
- EnumT = Cond->getType()->getAsAdjusted<EnumType>();
+ // Get the canonical type to handle typedefs.
+ EnumT = Cond->getType().getCanonicalType()->getAsAdjusted<EnumType>();
if (!EnumT)
return false;
EnumD = EnumT->getDecl();
@@ -152,14 +153,30 @@
if (CS->caseStmtIsGNURange())
return false;
+ // Support for direct references to enum constants. This is required to
+ // support C and ObjC which don't contain values in their ConstantExprs.
+ // The general way to get the value of a case is EvaluateAsRValue, but we'd
+ // rather not deal with that in case the AST is broken.
+ if (auto *DRE = dyn_cast<DeclRefExpr>(CS->getLHS()->IgnoreParenCasts())) {
+ if (auto *Enumerator = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
+ auto Iter = ExpectedCases.find(Normalize(Enumerator->getInitVal()));
+ if (Iter != ExpectedCases.end())
+ Iter->second.setCovered();
+ continue;
+ }
+ }
+
+ // ConstantExprs with values are expected for C++, otherwise the storage
+ // kind will be None.
+
// Case expression is not a constant expression or is value-dependent,
// so we may not be able to work out which cases are covered.
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CS->getLHS());
if (!CE || CE->isValueDependent())
return false;
- // Unsure if this case could ever come up, but prevents an unreachable
- // executing in getResultAsAPSInt.
+ // We need a stored value in order to continue; currently both C and ObjC
+ // enums won't have one.
if (CE->getResultStorageKind() == ConstantExpr::RSK_None)
return false;
auto Iter = ExpectedCases.find(Normalize(CE->getResultAsAPSInt()));
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits