[cfe-commits] r64746 - in /cfe/trunk: include/clang/Basic/Diagnostic.h lib/Basic/Diagnostic.cpp
Chris Lattner
sabre at nondot.org
Mon Feb 16 22:49:55 PST 2009
Author: lattner
Date: Tue Feb 17 00:49:55 2009
New Revision: 64746
URL: http://llvm.org/viewvc/llvm-project?rev=64746&view=rev
Log:
fix notes so that they are always filtered with the same logic
as the last non-note diagnostic that preceeded them. This ensures
that diagnostics in main files which have notes with locations in
system headers get all the bits and pieces emitted or not in a
unit. This fixes PR3215.
Modified:
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/lib/Basic/Diagnostic.cpp
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=64746&r1=64745&r2=64746&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Feb 17 00:49:55 2009
@@ -106,6 +106,11 @@
/// fatal error is emitted, and is sticky.
bool ErrorOccurred;
bool FatalErrorOccurred;
+
+ /// LastDiagLevel - This is the level of the last diagnostic emitted. This is
+ /// used to emit continuation diagnostics with the same level as the
+ /// diagnostic that they follow.
+ Diagnostic::Level LastDiagLevel;
unsigned NumDiagnostics; // Number of diagnostics reported
unsigned NumErrors; // Number of diagnostics that are errors
@@ -161,11 +166,11 @@
bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
/// setDiagnosticMapping - This allows the client to specify that certain
- /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
+ /// warnings are ignored. Only WARNINGs and EXTENSIONs can be mapped.
void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
assert(Diag < diag::DIAG_UPPER_LIMIT &&
"Can only map builtin diagnostics");
- assert((isBuiltinNoteWarningOrExtension(Diag) || Map == diag::MAP_FATAL) &&
+ assert((isBuiltinWarningOrExtension(Diag) || Map == diag::MAP_FATAL) &&
"Cannot map errors!");
unsigned char &Slot = DiagMappings[Diag/2];
unsigned Bits = (Diag & 1)*4;
@@ -212,16 +217,16 @@
/// issue.
const char *getDescription(unsigned DiagID) const;
- /// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
- /// level of the specified diagnostic ID is a Note, Warning, or Extension.
- /// Note that this only works on builtin diagnostics, not custom ones.
- static bool isBuiltinNoteWarningOrExtension(unsigned DiagID);
+ /// isNoteWarningOrExtension - Return true if the unmapped diagnostic
+ /// level of the specified diagnostic ID is a Warning or Extension.
+ /// This only works on builtin diagnostics, not custom ones, and is not legal to
+ /// call on NOTEs.
+ static bool isBuiltinWarningOrExtension(unsigned DiagID);
/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
/// object, classify the specified diagnostic ID into a Level, consumable by
/// the DiagnosticClient.
- Level getDiagnosticLevel(unsigned DiagID) const;
-
+ Level getDiagnosticLevel(unsigned DiagID) const;
/// Report - Issue the message to the client. @c DiagID is a member of the
/// @c diag::kind enum. This actually returns aninstance of DiagnosticBuilder
@@ -231,6 +236,10 @@
inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
private:
+ /// getDiagnosticLevel - This is an internal implementation helper used when
+ /// DiagClass is already known.
+ Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const;
+
// This is private state used by DiagnosticBuilder. We put it here instead of
// in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight
// object. This implementation choice means that we can only have one
Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=64746&r1=64745&r2=64746&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Tue Feb 17 00:49:55 2009
@@ -196,6 +196,7 @@
NumErrors = 0;
CustomDiagInfo = 0;
CurDiagID = ~0U;
+ LastDiagLevel = Fatal;
ArgToStringFn = DummyArgToStringFn;
}
@@ -214,10 +215,11 @@
}
-/// isBuiltinNoteWarningOrExtension - Return true if the unmapped diagnostic
-/// level of the specified diagnostic ID is a Note, Warning, or Extension.
-/// Note that this only works on builtin diagnostics, not custom ones.
-bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) {
+/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
+/// level of the specified diagnostic ID is a Warning or Extension.
+/// This only works on builtin diagnostics, not custom ones, and is not legal to
+/// call on NOTEs.
+bool Diagnostic::isBuiltinWarningOrExtension(unsigned DiagID) {
return DiagID < diag::DIAG_UPPER_LIMIT && getBuiltinDiagClass(DiagID) < ERROR;
}
@@ -225,21 +227,18 @@
/// getDescription - Given a diagnostic ID, return a description of the
/// issue.
const char *Diagnostic::getDescription(unsigned DiagID) const {
- if (DiagID < diag::DIAG_UPPER_LIMIT) {
- if (DiagID < diag::DIAG_START_LEX)
- return DiagnosticTextCommon[DiagID];
- else if (DiagID < diag::DIAG_START_PARSE)
- return DiagnosticTextLex[DiagID - diag::DIAG_START_LEX - 1];
- else if (DiagID < diag::DIAG_START_AST)
- return DiagnosticTextParse[DiagID - diag::DIAG_START_PARSE - 1];
- else if (DiagID < diag::DIAG_START_SEMA)
- return DiagnosticTextAST[DiagID - diag::DIAG_START_AST - 1];
- else if (DiagID < diag::DIAG_START_ANALYSIS)
- return DiagnosticTextSema[DiagID - diag::DIAG_START_SEMA - 1];
- else if (DiagID < diag::DIAG_UPPER_LIMIT)
- return DiagnosticTextAnalysis[DiagID - diag::DIAG_START_ANALYSIS - 1];
- }
-
+ if (DiagID < diag::DIAG_START_LEX)
+ return DiagnosticTextCommon[DiagID];
+ else if (DiagID < diag::DIAG_START_PARSE)
+ return DiagnosticTextLex[DiagID - diag::DIAG_START_LEX - 1];
+ else if (DiagID < diag::DIAG_START_AST)
+ return DiagnosticTextParse[DiagID - diag::DIAG_START_PARSE - 1];
+ else if (DiagID < diag::DIAG_START_SEMA)
+ return DiagnosticTextAST[DiagID - diag::DIAG_START_AST - 1];
+ else if (DiagID < diag::DIAG_START_ANALYSIS)
+ return DiagnosticTextSema[DiagID - diag::DIAG_START_SEMA - 1];
+ else if (DiagID < diag::DIAG_UPPER_LIMIT)
+ return DiagnosticTextAnalysis[DiagID - diag::DIAG_START_ANALYSIS - 1];
return CustomDiagInfo->getDescription(DiagID);
}
@@ -252,19 +251,23 @@
return CustomDiagInfo->getLevel(DiagID);
unsigned DiagClass = getBuiltinDiagClass(DiagID);
-
+ assert(DiagClass != NOTE && "Cannot get the diagnostic level of a note!");
+ return getDiagnosticLevel(DiagID, DiagClass);
+}
+
+/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+/// object, classify the specified diagnostic ID into a Level, consumable by
+/// the DiagnosticClient.
+Diagnostic::Level
+Diagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const {
// Specific non-error diagnostics may be mapped to various levels from ignored
- // to error.
- if (DiagClass < ERROR) {
- switch (getDiagnosticMapping((diag::kind)DiagID)) {
- case diag::MAP_DEFAULT: break;
- case diag::MAP_IGNORE: return Diagnostic::Ignored;
- case diag::MAP_WARNING: DiagClass = WARNING; break;
- case diag::MAP_ERROR: DiagClass = ERROR; break;
- case diag::MAP_FATAL: DiagClass = FATAL; break;
- }
- } else if (getDiagnosticMapping((diag::kind)DiagID) == diag::MAP_FATAL) {
- DiagClass = FATAL;
+ // to error. Errors can only be mapped to fatal.
+ switch (getDiagnosticMapping((diag::kind)DiagID)) {
+ case diag::MAP_DEFAULT: break;
+ case diag::MAP_IGNORE: return Diagnostic::Ignored;
+ case diag::MAP_WARNING: DiagClass = WARNING; break;
+ case diag::MAP_ERROR: DiagClass = ERROR; break;
+ case diag::MAP_FATAL: DiagClass = FATAL; break;
}
// Map diagnostic classes based on command line argument settings.
@@ -289,7 +292,6 @@
switch (DiagClass) {
default: assert(0 && "Unknown diagnostic class!");
- case NOTE: return Diagnostic::Note;
case WARNING: return Diagnostic::Warning;
case ERROR: return Diagnostic::Error;
case FATAL: return Diagnostic::Fatal;
@@ -307,23 +309,55 @@
return;
// Figure out the diagnostic level of this message.
- Diagnostic::Level DiagLevel = getDiagnosticLevel(Info.getID());
+ Diagnostic::Level DiagLevel;
+ unsigned DiagID = Info.getID();
- // If the client doesn't care about this message, don't issue it.
- if (DiagLevel == Diagnostic::Ignored)
+ // ShouldEmitInSystemHeader - True if this diagnostic should be produced even
+ // in a system header.
+ bool ShouldEmitInSystemHeader;
+
+ if (DiagID >= diag::DIAG_UPPER_LIMIT) {
+ // Handle custom diagnostics, which cannot be mapped.
+ DiagLevel = CustomDiagInfo->getLevel(DiagID);
+
+ // Custom diagnostics always are emitted in system headers.
+ ShouldEmitInSystemHeader = true;
+ } else {
+ // Get the class of the diagnostic. If this is a NOTE, map it onto whatever
+ // the diagnostic level was for the previous diagnostic so that it is
+ // filtered the same as the previous diagnostic.
+ unsigned DiagClass = getBuiltinDiagClass(DiagID);
+ if (DiagClass == NOTE) {
+ DiagLevel = Diagnostic::Note;
+ ShouldEmitInSystemHeader = false; // extra consideration is needed
+ } else {
+ // If this is not an error and we are in a system header, we ignore it.
+ // Check the original Diag ID here, because we also want to ignore
+ // extensions and warnings in -Werror and -pedantic-errors modes, which
+ // *map* warnings/extensions to errors.
+ ShouldEmitInSystemHeader = DiagClass == ERROR;
+
+ DiagLevel = getDiagnosticLevel(DiagID, DiagClass);
+ }
+ }
+
+ if (DiagLevel != Diagnostic::Note)
+ LastDiagLevel = DiagLevel;
+
+ // If the client doesn't care about this message, don't issue it. If this is
+ // a note and the last real diagnostic was ignored, ignore it too.
+ if (DiagLevel == Diagnostic::Ignored ||
+ (DiagLevel == Diagnostic::Note && LastDiagLevel == Diagnostic::Ignored))
return;
- // If this is not an error and we are in a system header, ignore it. We
- // have to check on the original Diag ID here, because we also want to
- // ignore extensions and warnings in -Werror and -pedantic-errors modes,
- // which *map* warnings/extensions to errors.
- if (SuppressSystemWarnings &&
- Info.getID() < diag::DIAG_UPPER_LIMIT &&
- getBuiltinDiagClass(Info.getID()) != ERROR &&
+ // If this diagnostic is in a system header and is not a clang error, suppress
+ // it.
+ if (SuppressSystemWarnings && !ShouldEmitInSystemHeader &&
Info.getLocation().isValid() &&
- Info.getLocation().getSpellingLoc().isInSystemHeader())
+ Info.getLocation().getSpellingLoc().isInSystemHeader() &&
+ (DiagLevel != Diagnostic::Note || LastDiagLevel == Diagnostic::Ignored))
return;
-
+
if (DiagLevel >= Diagnostic::Error) {
ErrorOccurred = true;
++NumErrors;
@@ -331,7 +365,7 @@
if (DiagLevel == Diagnostic::Fatal)
FatalErrorOccurred = true;
}
-
+
// Finally, report it.
Client->HandleDiagnostic(DiagLevel, Info);
if (Client->IncludeInDiagnosticCounts()) ++NumDiagnostics;
More information about the cfe-commits
mailing list