Skip to content

Commit 7838fc0

Browse files
authored
[Clang] [NFC] Move diagnostics emitting code from DiagnosticIDs into DiagnosticsEngine (#143517)
It makes more sense for this functionality to be all in one place rather than split up across two files—at least it caused me a bit of a headache to try and find all places where we were actually forwarding the diagnostic to the `DiagnosticConsumer`. Moreover, moving these functions into `DiagnosticsEngine` simplifies the code quite a bit since we access members of `DiagnosticsEngine` more frequently than those of `DiagnosticIDs`. There was also a duplicated code snippet that I’ve moved out into a new function.
1 parent 625bfb7 commit 7838fc0

File tree

4 files changed

+102
-128
lines changed

4 files changed

+102
-128
lines changed

clang/include/clang/Basic/Diagnostic.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/Basic/DiagnosticOptions.h"
1919
#include "clang/Basic/SourceLocation.h"
2020
#include "clang/Basic/Specifiers.h"
21+
#include "clang/Basic/UnsignedOrNone.h"
2122
#include "llvm/ADT/ArrayRef.h"
2223
#include "llvm/ADT/DenseMap.h"
2324
#include "llvm/ADT/FunctionExtras.h"
@@ -49,6 +50,7 @@ class FileSystem;
4950
namespace clang {
5051

5152
class DeclContext;
53+
class Diagnostic;
5254
class DiagnosticBuilder;
5355
class DiagnosticConsumer;
5456
class IdentifierInfo;
@@ -228,6 +230,8 @@ class DiagStorageAllocator {
228230
class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
229231
public:
230232
/// The level of the diagnostic, after it has been through mapping.
233+
// FIXME: Make this an alias for DiagnosticIDs::Level as soon as
234+
// we can use 'using enum'.
231235
enum Level {
232236
Ignored = DiagnosticIDs::Ignored,
233237
Note = DiagnosticIDs::Note,
@@ -532,7 +536,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
532536
///
533537
/// This is used to emit continuation diagnostics with the same level as the
534538
/// diagnostic that they follow.
535-
DiagnosticIDs::Level LastDiagLevel;
539+
Level LastDiagLevel;
536540

537541
/// Number of warnings reported
538542
unsigned NumWarnings;
@@ -777,18 +781,16 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
777781
/// the middle of another diagnostic.
778782
///
779783
/// This can be used by clients who suppress diagnostics themselves.
780-
void setLastDiagnosticIgnored(bool Ignored) {
781-
if (LastDiagLevel == DiagnosticIDs::Fatal)
784+
void setLastDiagnosticIgnored(bool IsIgnored) {
785+
if (LastDiagLevel == Fatal)
782786
FatalErrorOccurred = true;
783-
LastDiagLevel = Ignored ? DiagnosticIDs::Ignored : DiagnosticIDs::Warning;
787+
LastDiagLevel = IsIgnored ? Ignored : Warning;
784788
}
785789

786790
/// Determine whether the previous diagnostic was ignored. This can
787791
/// be used by clients that want to determine whether notes attached to a
788792
/// diagnostic will be suppressed.
789-
bool isLastDiagnosticIgnored() const {
790-
return LastDiagLevel == DiagnosticIDs::Ignored;
791-
}
793+
bool isLastDiagnosticIgnored() const { return LastDiagLevel == Ignored; }
792794

793795
/// Controls whether otherwise-unmapped extension diagnostics are
794796
/// mapped onto ignore/warning/error.
@@ -1024,9 +1026,10 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
10241026
/// Used to report a diagnostic that is finally fully formed.
10251027
///
10261028
/// \returns true if the diagnostic was emitted, false if it was suppressed.
1027-
bool ProcessDiag(const DiagnosticBuilder &DiagBuilder) {
1028-
return Diags->ProcessDiag(*this, DiagBuilder);
1029-
}
1029+
bool ProcessDiag(const DiagnosticBuilder &DiagBuilder);
1030+
1031+
/// Forward a diagnostic to the DiagnosticConsumer.
1032+
void Report(Level DiagLevel, const Diagnostic &Info);
10301033

10311034
/// @name Diagnostic Emission
10321035
/// @{

clang/include/clang/Basic/DiagnosticIDs.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -483,18 +483,6 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
483483

484484
Class getDiagClass(unsigned DiagID) const;
485485

486-
/// Used to report a diagnostic that is finally fully formed.
487-
///
488-
/// \returns \c true if the diagnostic was emitted, \c false if it was
489-
/// suppressed.
490-
bool ProcessDiag(DiagnosticsEngine &Diag,
491-
const DiagnosticBuilder &DiagBuilder) const;
492-
493-
/// Used to emit a diagnostic that is finally fully formed,
494-
/// ignoring suppression.
495-
void EmitDiag(DiagnosticsEngine &Diag, const DiagnosticBuilder &DiagBuilder,
496-
Level DiagLevel) const;
497-
498486
/// Whether the diagnostic may leave the AST in a state where some
499487
/// invariants can break.
500488
bool isUnrecoverable(unsigned DiagID) const;

clang/lib/Basic/Diagnostic.cpp

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ void DiagnosticsEngine::Reset(bool soft /*=false*/) {
130130
TrapNumErrorsOccurred = 0;
131131
TrapNumUnrecoverableErrorsOccurred = 0;
132132

133-
LastDiagLevel = DiagnosticIDs::Ignored;
133+
LastDiagLevel = Ignored;
134134

135135
if (!soft) {
136136
// Clear state related to #pragma diagnostic.
@@ -658,13 +658,95 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
658658
Level DiagLevel = storedDiag.getLevel();
659659
Diagnostic Info(this, storedDiag.getLocation(), storedDiag.getID(),
660660
DiagStorage, storedDiag.getMessage());
661+
Report(DiagLevel, Info);
662+
}
663+
664+
void DiagnosticsEngine::Report(Level DiagLevel, const Diagnostic &Info) {
665+
assert(DiagLevel != Ignored && "Cannot emit ignored diagnostics!");
661666
Client->HandleDiagnostic(DiagLevel, Info);
662667
if (Client->IncludeInDiagnosticCounts()) {
663-
if (DiagLevel == DiagnosticsEngine::Warning)
668+
if (DiagLevel == Warning)
664669
++NumWarnings;
665670
}
666671
}
667672

673+
/// ProcessDiag - This is the method used to report a diagnostic that is
674+
/// finally fully formed.
675+
bool DiagnosticsEngine::ProcessDiag(const DiagnosticBuilder &DiagBuilder) {
676+
Diagnostic Info(this, DiagBuilder);
677+
678+
assert(getClient() && "DiagnosticClient not set!");
679+
680+
// Figure out the diagnostic level of this message.
681+
unsigned DiagID = Info.getID();
682+
Level DiagLevel = getDiagnosticLevel(DiagID, Info.getLocation());
683+
684+
// Update counts for DiagnosticErrorTrap even if a fatal error occurred
685+
// or diagnostics are suppressed.
686+
if (DiagLevel >= Error) {
687+
++TrapNumErrorsOccurred;
688+
if (Diags->isUnrecoverable(DiagID))
689+
++TrapNumUnrecoverableErrorsOccurred;
690+
}
691+
692+
if (SuppressAllDiagnostics)
693+
return false;
694+
695+
if (DiagLevel != Note) {
696+
// Record that a fatal error occurred only when we see a second
697+
// non-note diagnostic. This allows notes to be attached to the
698+
// fatal error, but suppresses any diagnostics that follow those
699+
// notes.
700+
if (LastDiagLevel == Fatal)
701+
FatalErrorOccurred = true;
702+
703+
LastDiagLevel = DiagLevel;
704+
}
705+
706+
// If a fatal error has already been emitted, silence all subsequent
707+
// diagnostics.
708+
if (FatalErrorOccurred) {
709+
if (DiagLevel >= Error && Client->IncludeInDiagnosticCounts())
710+
++NumErrors;
711+
712+
return false;
713+
}
714+
715+
// If the client doesn't care about this message, don't issue it. If this is
716+
// a note and the last real diagnostic was ignored, ignore it too.
717+
if (DiagLevel == Ignored || (DiagLevel == Note && LastDiagLevel == Ignored))
718+
return false;
719+
720+
if (DiagLevel >= Error) {
721+
if (Diags->isUnrecoverable(DiagID))
722+
UnrecoverableErrorOccurred = true;
723+
724+
// Warnings which have been upgraded to errors do not prevent compilation.
725+
if (Diags->isDefaultMappingAsError(DiagID))
726+
UncompilableErrorOccurred = true;
727+
728+
ErrorOccurred = true;
729+
if (Client->IncludeInDiagnosticCounts())
730+
++NumErrors;
731+
732+
// If we've emitted a lot of errors, emit a fatal error instead of it to
733+
// stop a flood of bogus errors.
734+
if (ErrorLimit && NumErrors > ErrorLimit && DiagLevel == Error) {
735+
Report(diag::fatal_too_many_errors);
736+
return false;
737+
}
738+
}
739+
740+
// Make sure we set FatalErrorOccurred to ensure that the notes from the
741+
// diagnostic that caused `fatal_too_many_errors` won't be emitted.
742+
if (Info.getID() == diag::fatal_too_many_errors)
743+
FatalErrorOccurred = true;
744+
745+
// Finally, report it.
746+
Report(DiagLevel, Info);
747+
return true;
748+
}
749+
668750
bool DiagnosticsEngine::EmitDiagnostic(const DiagnosticBuilder &DB,
669751
bool Force) {
670752
assert(getClient() && "DiagnosticClient not set!");
@@ -674,14 +756,12 @@ bool DiagnosticsEngine::EmitDiagnostic(const DiagnosticBuilder &DB,
674756
Diagnostic Info(this, DB);
675757

676758
// Figure out the diagnostic level of this message.
677-
DiagnosticIDs::Level DiagLevel =
678-
Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this);
759+
Level DiagLevel = getDiagnosticLevel(Info.getID(), Info.getLocation());
679760

680-
Emitted = (DiagLevel != DiagnosticIDs::Ignored);
681-
if (Emitted) {
682-
// Emit the diagnostic regardless of suppression level.
683-
Diags->EmitDiag(*this, DB, DiagLevel);
684-
}
761+
// Emit the diagnostic regardless of suppression level.
762+
Emitted = DiagLevel != Ignored;
763+
if (Emitted)
764+
Report(DiagLevel, Info);
685765
} else {
686766
// Process the diagnostic, sending the accumulated information to the
687767
// DiagnosticConsumer.

clang/lib/Basic/DiagnosticIDs.cpp

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -823,103 +823,6 @@ unsigned DiagnosticIDs::getCXXCompatDiagId(const LangOptions &LangOpts,
823823
return StdVer >= D.StdVer ? D.DiagId : D.PreDiagId;
824824
}
825825

826-
/// ProcessDiag - This is the method used to report a diagnostic that is
827-
/// finally fully formed.
828-
bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag,
829-
const DiagnosticBuilder &DiagBuilder) const {
830-
Diagnostic Info(&Diag, DiagBuilder);
831-
832-
assert(Diag.getClient() && "DiagnosticClient not set!");
833-
834-
// Figure out the diagnostic level of this message.
835-
unsigned DiagID = Info.getID();
836-
DiagnosticIDs::Level DiagLevel
837-
= getDiagnosticLevel(DiagID, Info.getLocation(), Diag);
838-
839-
// Update counts for DiagnosticErrorTrap even if a fatal error occurred
840-
// or diagnostics are suppressed.
841-
if (DiagLevel >= DiagnosticIDs::Error) {
842-
++Diag.TrapNumErrorsOccurred;
843-
if (isUnrecoverable(DiagID))
844-
++Diag.TrapNumUnrecoverableErrorsOccurred;
845-
}
846-
847-
if (Diag.SuppressAllDiagnostics)
848-
return false;
849-
850-
if (DiagLevel != DiagnosticIDs::Note) {
851-
// Record that a fatal error occurred only when we see a second
852-
// non-note diagnostic. This allows notes to be attached to the
853-
// fatal error, but suppresses any diagnostics that follow those
854-
// notes.
855-
if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
856-
Diag.FatalErrorOccurred = true;
857-
858-
Diag.LastDiagLevel = DiagLevel;
859-
}
860-
861-
// If a fatal error has already been emitted, silence all subsequent
862-
// diagnostics.
863-
if (Diag.FatalErrorOccurred) {
864-
if (DiagLevel >= DiagnosticIDs::Error &&
865-
Diag.Client->IncludeInDiagnosticCounts()) {
866-
++Diag.NumErrors;
867-
}
868-
869-
return false;
870-
}
871-
872-
// If the client doesn't care about this message, don't issue it. If this is
873-
// a note and the last real diagnostic was ignored, ignore it too.
874-
if (DiagLevel == DiagnosticIDs::Ignored ||
875-
(DiagLevel == DiagnosticIDs::Note &&
876-
Diag.LastDiagLevel == DiagnosticIDs::Ignored))
877-
return false;
878-
879-
if (DiagLevel >= DiagnosticIDs::Error) {
880-
if (isUnrecoverable(DiagID))
881-
Diag.UnrecoverableErrorOccurred = true;
882-
883-
// Warnings which have been upgraded to errors do not prevent compilation.
884-
if (isDefaultMappingAsError(DiagID))
885-
Diag.UncompilableErrorOccurred = true;
886-
887-
Diag.ErrorOccurred = true;
888-
if (Diag.Client->IncludeInDiagnosticCounts()) {
889-
++Diag.NumErrors;
890-
}
891-
892-
// If we've emitted a lot of errors, emit a fatal error instead of it to
893-
// stop a flood of bogus errors.
894-
if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit &&
895-
DiagLevel == DiagnosticIDs::Error) {
896-
Diag.Report(diag::fatal_too_many_errors);
897-
return false;
898-
}
899-
}
900-
901-
// Make sure we set FatalErrorOccurred to ensure that the notes from the
902-
// diagnostic that caused `fatal_too_many_errors` won't be emitted.
903-
if (Info.getID() == diag::fatal_too_many_errors)
904-
Diag.FatalErrorOccurred = true;
905-
// Finally, report it.
906-
EmitDiag(Diag, DiagBuilder, DiagLevel);
907-
return true;
908-
}
909-
910-
void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag,
911-
const DiagnosticBuilder &DiagBuilder,
912-
Level DiagLevel) const {
913-
Diagnostic Info(&Diag, DiagBuilder);
914-
assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!");
915-
916-
Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
917-
if (Diag.Client->IncludeInDiagnosticCounts()) {
918-
if (DiagLevel == DiagnosticIDs::Warning)
919-
++Diag.NumWarnings;
920-
}
921-
}
922-
923826
bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
924827
// Only errors may be unrecoverable.
925828
if (getDiagClass(DiagID) < CLASS_ERROR)

0 commit comments

Comments
 (0)