aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-09-16 17:09:42 +0000
committerChris Lattner <sabre@nondot.org>2010-09-16 17:09:42 +0000
commitce78461303f45fecb3460d1c49c9b71f27ad19c3 (patch)
tree4199fe41edcca4d15d43147ba5d07616418ecec5 /lib/Sema/SemaStmt.cpp
parentd754d5546ef1faa4216298fd95bc6a7f15808fd2 (diff)
improve the "enumeration value 'g' not handled in switch"
warning to handle multiple enumerators with one warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114093 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index c9a6da13fb..8ec12a460d 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -703,7 +703,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// we still do the analysis to preserve this information in the AST
// (which can be used by flow-based analyes).
//
- const EnumType* ET = CondTypeBeforePromotion->getAs<EnumType>();
+ const EnumType *ET = CondTypeBeforePromotion->getAs<EnumType>();
// If switch has default case, then ignore it.
if (!CaseListIsErroneous && !HasConstantCond && ET) {
@@ -760,13 +760,16 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
<< ED->getDeclName();
}
}
+
// Check which enum vals aren't in switch
CaseValsTy::const_iterator CI = CaseVals.begin();
CaseRangesTy::const_iterator RI = CaseRanges.begin();
bool hasCasesNotInSwitch = false;
+ llvm::SmallVector<DeclarationName,8> UnhandledNames;
+
for (EnumValsTy::const_iterator EI = EnumVals.begin(); EI != EIend; EI++){
- //Drop unneeded case values
+ // Drop unneeded case values
llvm::APSInt CIVal;
while (CI != CaseVals.end() && CI->first < EI->first)
CI++;
@@ -784,10 +787,31 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
if (RI == CaseRanges.end() || EI->first < RI->first) {
hasCasesNotInSwitch = true;
if (!TheDefaultStmt)
- Diag(CondExpr->getExprLoc(), diag::warn_missing_cases)
- << EI->second->getDeclName();
+ UnhandledNames.push_back(EI->second->getDeclName());
}
}
+
+ // Produce a nice diagnostic if multiple values aren't handled.
+ switch (UnhandledNames.size()) {
+ case 0: break;
+ case 1:
+ Diag(CondExpr->getExprLoc(), diag::warn_missing_case1)
+ << UnhandledNames[0];
+ break;
+ case 2:
+ Diag(CondExpr->getExprLoc(), diag::warn_missing_case2)
+ << UnhandledNames[0] << UnhandledNames[1];
+ break;
+ case 3:
+ Diag(CondExpr->getExprLoc(), diag::warn_missing_case3)
+ << UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
+ break;
+ default:
+ Diag(CondExpr->getExprLoc(), diag::warn_missing_cases)
+ << (unsigned)UnhandledNames.size()
+ << UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
+ break;
+ }
if (!hasCasesNotInSwitch)
SS->setAllEnumCasesCovered();