Make DiagnosticErrorTrap keep a count of the errors that occurred so multiple

DiagnosticErrorTraps can be composed (e.g. a trap inside another trap).

Fixes http://llvm.org/PR10462 & rdar://9852007.

llvm-svn: 136447
This commit is contained in:
Argyrios Kyrtzidis 2011-07-29 01:25:44 +00:00
parent 7eadbeaf62
commit 1fa8b4b204
4 changed files with 40 additions and 11 deletions

View File

@ -255,10 +255,10 @@ private:
/// \brief Indicates that an unrecoverable error has occurred.
bool UnrecoverableErrorOccurred;
/// \brief Toggles for DiagnosticErrorTrap to check whether an error occurred
/// \brief Counts for DiagnosticErrorTrap to check whether an error occurred
/// during a parsing section, e.g. during parsing a function.
bool TrapErrorOccurred;
bool TrapUnrecoverableErrorOccurred;
unsigned TrapNumErrorsOccurred;
unsigned TrapNumUnrecoverableErrorsOccurred;
/// LastDiagLevel - This is the level of the last diagnostic emitted. This is
/// used to emit continuation diagnostics with the same level as the
@ -639,6 +639,8 @@ private:
/// queried.
class DiagnosticErrorTrap {
Diagnostic &Diag;
unsigned NumErrors;
unsigned NumUnrecoverableErrors;
public:
explicit DiagnosticErrorTrap(Diagnostic &Diag)
@ -647,19 +649,19 @@ public:
/// \brief Determine whether any errors have occurred since this
/// object instance was created.
bool hasErrorOccurred() const {
return Diag.TrapErrorOccurred;
return Diag.TrapNumErrorsOccurred > NumErrors;
}
/// \brief Determine whether any unrecoverable errors have occurred since this
/// object instance was created.
bool hasUnrecoverableErrorOccurred() const {
return Diag.TrapUnrecoverableErrorOccurred;
return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors;
}
// Set to initial state of "no errors occurred".
void reset() {
Diag.TrapErrorOccurred = false;
Diag.TrapUnrecoverableErrorOccurred = false;
NumErrors = Diag.TrapNumErrorsOccurred;
NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred;
}
};

View File

@ -92,6 +92,8 @@ void Diagnostic::Reset() {
NumWarnings = 0;
NumErrors = 0;
NumErrorsSuppressed = 0;
TrapNumErrorsOccurred = 0;
TrapNumUnrecoverableErrorsOccurred = 0;
CurDiagID = ~0U;
// Set LastDiagLevel to an "unset" state. If we set it to 'Ignored', notes

View File

@ -665,6 +665,13 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
Diag.LastDiagLevel = DiagLevel;
}
// Update counts for DiagnosticErrorTrap even if a fatal error occurred.
if (DiagLevel >= DiagnosticIDs::Error) {
++Diag.TrapNumErrorsOccurred;
if (isUnrecoverable(DiagID))
++Diag.TrapNumUnrecoverableErrorsOccurred;
}
// If a fatal error has already been emitted, silence all subsequent
// diagnostics.
if (Diag.FatalErrorOccurred) {
@ -685,11 +692,8 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
return false;
if (DiagLevel >= DiagnosticIDs::Error) {
Diag.TrapErrorOccurred = true;
if (isUnrecoverable(DiagID)) {
Diag.TrapUnrecoverableErrorOccurred = true;
if (isUnrecoverable(DiagID))
Diag.UnrecoverableErrorOccurred = true;
}
if (Diag.Client->IncludeInDiagnosticCounts()) {
Diag.ErrorOccurred = true;

View File

@ -171,3 +171,24 @@ namespace test9 {
}
}
}
// http://llvm.org/PR10462
namespace PR10462 {
enum MyEnum {
something_valid,
something_invalid
};
bool recurse() {
MyEnum K;
switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
case something_valid:
case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
int *X = 0;
if (recurse()) {
}
break;
}
}
}