@@ -804,6 +804,21 @@ static DiagnosticKind toDiagnosticKind(DiagnosticBehavior behavior) {
804804 llvm_unreachable (" Unhandled DiagnosticKind in switch." );
805805}
806806
807+ static
808+ DiagnosticBehavior toDiagnosticBehavior (DiagnosticKind kind, bool isFatal) {
809+ switch (kind) {
810+ case DiagnosticKind::Note:
811+ return DiagnosticBehavior::Note;
812+ case DiagnosticKind::Error:
813+ return isFatal ? DiagnosticBehavior::Fatal : DiagnosticBehavior::Error;
814+ case DiagnosticKind::Warning:
815+ return DiagnosticBehavior::Warning;
816+ case DiagnosticKind::Remark:
817+ return DiagnosticBehavior::Remark;
818+ }
819+ llvm_unreachable (" Unhandled DiagnosticKind in switch." );
820+ }
821+
807822// A special option only for compiler writers that causes Diagnostics to assert
808823// when a failure diagnostic is emitted. Intended for use in the debugger.
809824llvm::cl::opt<bool > AssertOnError (" swift-diagnostics-assert-on-error" ,
@@ -814,77 +829,62 @@ llvm::cl::opt<bool> AssertOnWarning("swift-diagnostics-assert-on-warning",
814829 llvm::cl::init (false ));
815830
816831DiagnosticBehavior DiagnosticState::determineBehavior (const Diagnostic &diag) {
817- auto set = [this ](DiagnosticBehavior lvl) {
818- if (lvl == DiagnosticBehavior::Fatal) {
819- fatalErrorOccurred = true ;
820- anyErrorOccurred = true ;
821- } else if (lvl == DiagnosticBehavior::Error) {
822- anyErrorOccurred = true ;
823- }
824-
825- assert ((!AssertOnError || !anyErrorOccurred) && " We emitted an error?!" );
826- assert ((!AssertOnWarning || (lvl != DiagnosticBehavior::Warning)) &&
827- " We emitted a warning?!" );
828- previousBehavior = lvl;
829- return lvl;
830- };
831-
832832 // We determine how to handle a diagnostic based on the following rules
833- // 1) If current state dictates a certain behavior, follow that
834- // 2) If the user ignored this specific diagnostic, follow that
835- // 3) If the user provided a behavior for this diagnostic's kind, follow
836- // that
837- // 4) Otherwise remap the diagnostic kind, applying the behaviorLimit
838-
833+ // 1) Map the diagnostic to its "intended" behavior, applying the behavior
834+ // limit for this particular emission
835+ // 2) If current state dictates a certain behavior, follow that
836+ // 3) If the user ignored this specific diagnostic, follow that
837+ // 4) If the user substituted a different behavior for this behavior, apply
838+ // that change
839+ // 5) Update current state for use during the next diagnostic
840+
841+ // 1) Map the diagnostic to its "intended" behavior, applying the behavior
842+ // limit for this particular emission
839843 auto diagInfo = storedDiagnosticInfos[(unsigned )diag.getID ()];
840- bool isNote = diagInfo.kind == DiagnosticKind::Note
841- || diag.getBehaviorLimit () == DiagnosticBehavior::Note;
844+ DiagnosticBehavior lvl =
845+ std::max (toDiagnosticBehavior (diagInfo.kind , diagInfo.isFatal ),
846+ diag.getBehaviorLimit ());
847+ assert (lvl != DiagnosticBehavior::Unspecified);
842848
843- // 1 ) If current state dictates a certain behavior, follow that
849+ // 2 ) If current state dictates a certain behavior, follow that
844850
845851 // Notes relating to ignored diagnostics should also be ignored
846- if (previousBehavior == DiagnosticBehavior::Ignore && isNote)
847- return set (DiagnosticBehavior::Ignore);
852+ if (previousBehavior == DiagnosticBehavior::Ignore
853+ && lvl == DiagnosticBehavior::Note)
854+ lvl = DiagnosticBehavior::Ignore;
848855
849856 // Suppress diagnostics when in a fatal state, except for follow-on notes
850857 if (fatalErrorOccurred)
851- if (!showDiagnosticsAfterFatalError && !isNote )
852- return set ( DiagnosticBehavior::Ignore) ;
858+ if (!showDiagnosticsAfterFatalError && lvl != DiagnosticBehavior::Note )
859+ lvl = DiagnosticBehavior::Ignore;
853860
854- // 2 ) If the user ignored this specific diagnostic, follow that
861+ // 3 ) If the user ignored this specific diagnostic, follow that
855862 if (ignoredDiagnostics[(unsigned )diag.getID ()])
856- return set ( DiagnosticBehavior::Ignore) ;
863+ lvl = DiagnosticBehavior::Ignore;
857864
858- // 3) If the user provided a behavior for this diagnostic's kind, follow
859- // that
860- if (diagInfo.kind == DiagnosticKind::Warning
861- || (diag.getBehaviorLimit () == DiagnosticBehavior::Warning && !isNote)) {
862- if (suppressWarnings)
863- return set (DiagnosticBehavior::Ignore);
865+ // 4) If the user substituted a different behavior for this behavior, apply
866+ // that change
867+ if (lvl == DiagnosticBehavior::Warning) {
864868 if (warningsAsErrors)
865- return set (DiagnosticBehavior::Error);
869+ lvl = DiagnosticBehavior::Error;
870+ if (suppressWarnings)
871+ lvl = DiagnosticBehavior::Ignore;
866872 }
867873
868- // 4) Otherwise remap the diagnostic kind, applying the behaviorLimit
869- DiagnosticBehavior lvl = DiagnosticBehavior::Unspecified;
870- switch (diagInfo.kind ) {
871- case DiagnosticKind::Note:
872- lvl = DiagnosticBehavior::Note;
873- break ;
874- case DiagnosticKind::Error:
875- lvl = diagInfo.isFatal ? DiagnosticBehavior::Fatal
876- : DiagnosticBehavior::Error;
877- break ;
878- case DiagnosticKind::Warning:
879- lvl = DiagnosticBehavior::Warning;
880- break ;
881- case DiagnosticKind::Remark:
882- lvl = DiagnosticBehavior::Remark;
883- break ;
874+ // 5) Update current state for use during the next diagnostic
875+ if (lvl == DiagnosticBehavior::Fatal) {
876+ fatalErrorOccurred = true ;
877+ anyErrorOccurred = true ;
878+ } else if (lvl == DiagnosticBehavior::Error) {
879+ anyErrorOccurred = true ;
884880 }
885- assert (lvl != DiagnosticBehavior::Unspecified);
886881
887- return set (std::max (lvl, diag.getBehaviorLimit ()));
882+ assert ((!AssertOnError || !anyErrorOccurred) && " We emitted an error?!" );
883+ assert ((!AssertOnWarning || (lvl != DiagnosticBehavior::Warning)) &&
884+ " We emitted a warning?!" );
885+
886+ previousBehavior = lvl;
887+ return lvl;
888888}
889889
890890void DiagnosticEngine::flushActiveDiagnostic () {
0 commit comments