@@ -804,6 +804,21 @@ static DiagnosticKind toDiagnosticKind(DiagnosticBehavior behavior) {
804
804
llvm_unreachable (" Unhandled DiagnosticKind in switch." );
805
805
}
806
806
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
+
807
822
// A special option only for compiler writers that causes Diagnostics to assert
808
823
// when a failure diagnostic is emitted. Intended for use in the debugger.
809
824
llvm::cl::opt<bool > AssertOnError (" swift-diagnostics-assert-on-error" ,
@@ -814,77 +829,62 @@ llvm::cl::opt<bool> AssertOnWarning("swift-diagnostics-assert-on-warning",
814
829
llvm::cl::init (false ));
815
830
816
831
DiagnosticBehavior 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
-
832
832
// 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
839
843
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);
842
848
843
- // 1 ) If current state dictates a certain behavior, follow that
849
+ // 2 ) If current state dictates a certain behavior, follow that
844
850
845
851
// 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;
848
855
849
856
// Suppress diagnostics when in a fatal state, except for follow-on notes
850
857
if (fatalErrorOccurred)
851
- if (!showDiagnosticsAfterFatalError && !isNote )
852
- return set ( DiagnosticBehavior::Ignore) ;
858
+ if (!showDiagnosticsAfterFatalError && lvl != DiagnosticBehavior::Note )
859
+ lvl = DiagnosticBehavior::Ignore;
853
860
854
- // 2 ) If the user ignored this specific diagnostic, follow that
861
+ // 3 ) If the user ignored this specific diagnostic, follow that
855
862
if (ignoredDiagnostics[(unsigned )diag.getID ()])
856
- return set ( DiagnosticBehavior::Ignore) ;
863
+ lvl = DiagnosticBehavior::Ignore;
857
864
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) {
864
868
if (warningsAsErrors)
865
- return set (DiagnosticBehavior::Error);
869
+ lvl = DiagnosticBehavior::Error;
870
+ if (suppressWarnings)
871
+ lvl = DiagnosticBehavior::Ignore;
866
872
}
867
873
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 ;
884
880
}
885
- assert (lvl != DiagnosticBehavior::Unspecified);
886
881
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;
888
888
}
889
889
890
890
void DiagnosticEngine::flushActiveDiagnostic () {
0 commit comments