diff options
author | Chris Lattner <sabre@nondot.org> | 2010-09-16 17:09:42 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-09-16 17:09:42 +0000 |
commit | ce78461303f45fecb3460d1c49c9b71f27ad19c3 (patch) | |
tree | 4199fe41edcca4d15d43147ba5d07616418ecec5 /lib/Sema/SemaStmt.cpp | |
parent | d754d5546ef1faa4216298fd95bc6a7f15808fd2 (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.cpp | 32 |
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(); |