@@ -136,8 +136,8 @@ static constexpr EducationalNotes<LocalDiagID::NumDiags> _EducationalNotes = Edu
136
136
static constexpr auto educationalNotes = _EducationalNotes.value;
137
137
138
138
DiagnosticState::DiagnosticState () {
139
- // Initialize our per-diagnostic state to default
140
- perDiagnosticBehavior .resize (LocalDiagID::NumDiags, Behavior::Unspecified );
139
+ // Initialize our ignored diagnostics to default
140
+ ignoredDiagnostics .resize (LocalDiagID::NumDiags);
141
141
}
142
142
143
143
static CharSourceRange toCharSourceRange (SourceManager &SM, SourceRange SR) {
@@ -289,6 +289,12 @@ InFlightDiagnostic &InFlightDiagnostic::fixItExchange(SourceRange R1,
289
289
return *this ;
290
290
}
291
291
292
+ InFlightDiagnostic &
293
+ InFlightDiagnostic::limitBehavior (DiagnosticBehavior limit) {
294
+ Engine->getActiveDiagnostic ().setBehaviorLimit (limit);
295
+ return *this ;
296
+ }
297
+
292
298
void InFlightDiagnostic::flush () {
293
299
if (!IsActive)
294
300
return ;
@@ -779,26 +785,41 @@ void DiagnosticEngine::formatDiagnosticText(
779
785
}
780
786
}
781
787
782
- static DiagnosticKind toDiagnosticKind (DiagnosticState::Behavior behavior) {
788
+ static DiagnosticKind toDiagnosticKind (DiagnosticBehavior behavior) {
783
789
switch (behavior) {
784
- case DiagnosticState::Behavior ::Unspecified:
790
+ case DiagnosticBehavior ::Unspecified:
785
791
llvm_unreachable (" unspecified behavior" );
786
- case DiagnosticState::Behavior ::Ignore:
792
+ case DiagnosticBehavior ::Ignore:
787
793
llvm_unreachable (" trying to map an ignored diagnostic" );
788
- case DiagnosticState::Behavior ::Error:
789
- case DiagnosticState::Behavior ::Fatal:
794
+ case DiagnosticBehavior ::Error:
795
+ case DiagnosticBehavior ::Fatal:
790
796
return DiagnosticKind::Error;
791
- case DiagnosticState::Behavior ::Note:
797
+ case DiagnosticBehavior ::Note:
792
798
return DiagnosticKind::Note;
793
- case DiagnosticState::Behavior ::Warning:
799
+ case DiagnosticBehavior ::Warning:
794
800
return DiagnosticKind::Warning;
795
- case DiagnosticState::Behavior ::Remark:
801
+ case DiagnosticBehavior ::Remark:
796
802
return DiagnosticKind::Remark;
797
803
}
798
804
799
805
llvm_unreachable (" Unhandled DiagnosticKind in switch." );
800
806
}
801
807
808
+ static
809
+ DiagnosticBehavior toDiagnosticBehavior (DiagnosticKind kind, bool isFatal) {
810
+ switch (kind) {
811
+ case DiagnosticKind::Note:
812
+ return DiagnosticBehavior::Note;
813
+ case DiagnosticKind::Error:
814
+ return isFatal ? DiagnosticBehavior::Fatal : DiagnosticBehavior::Error;
815
+ case DiagnosticKind::Warning:
816
+ return DiagnosticBehavior::Warning;
817
+ case DiagnosticKind::Remark:
818
+ return DiagnosticBehavior::Remark;
819
+ }
820
+ llvm_unreachable (" Unhandled DiagnosticKind in switch." );
821
+ }
822
+
802
823
// A special option only for compiler writers that causes Diagnostics to assert
803
824
// when a failure diagnostic is emitted. Intended for use in the debugger.
804
825
llvm::cl::opt<bool > AssertOnError (" swift-diagnostics-assert-on-error" ,
@@ -808,72 +829,63 @@ llvm::cl::opt<bool> AssertOnError("swift-diagnostics-assert-on-error",
808
829
llvm::cl::opt<bool > AssertOnWarning (" swift-diagnostics-assert-on-warning" ,
809
830
llvm::cl::init (false ));
810
831
811
- DiagnosticState::Behavior DiagnosticState::determineBehavior (DiagID id) {
812
- auto set = [this ](DiagnosticState::Behavior lvl) {
813
- if (lvl == Behavior::Fatal) {
814
- fatalErrorOccurred = true ;
815
- anyErrorOccurred = true ;
816
- } else if (lvl == Behavior::Error) {
817
- anyErrorOccurred = true ;
818
- }
819
-
820
- assert ((!AssertOnError || !anyErrorOccurred) && " We emitted an error?!" );
821
- assert ((!AssertOnWarning || (lvl != Behavior::Warning)) &&
822
- " We emitted a warning?!" );
823
- previousBehavior = lvl;
824
- return lvl;
825
- };
826
-
832
+ DiagnosticBehavior DiagnosticState::determineBehavior (const Diagnostic &diag) {
827
833
// We determine how to handle a diagnostic based on the following rules
828
- // 1) If current state dictates a certain behavior, follow that
829
- // 2) If the user provided a behavior for this specific diagnostic, follow
830
- // that
831
- // 3) If the user provided a behavior for this diagnostic's kind, follow
832
- // that
833
- // 4) Otherwise remap the diagnostic kind
834
-
835
- auto diagInfo = storedDiagnosticInfos[(unsigned )id];
836
- bool isNote = diagInfo.kind == DiagnosticKind::Note;
837
-
838
- // 1) If current state dictates a certain behavior, follow that
834
+ // 1) Map the diagnostic to its "intended" behavior, applying the behavior
835
+ // limit for this particular emission
836
+ // 2) If current state dictates a certain behavior, follow that
837
+ // 3) If the user ignored this specific diagnostic, follow that
838
+ // 4) If the user substituted a different behavior for this behavior, apply
839
+ // that change
840
+ // 5) Update current state for use during the next diagnostic
841
+
842
+ // 1) Map the diagnostic to its "intended" behavior, applying the behavior
843
+ // limit for this particular emission
844
+ auto diagInfo = storedDiagnosticInfos[(unsigned )diag.getID ()];
845
+ DiagnosticBehavior lvl =
846
+ std::max (toDiagnosticBehavior (diagInfo.kind , diagInfo.isFatal ),
847
+ diag.getBehaviorLimit ());
848
+ assert (lvl != DiagnosticBehavior::Unspecified);
849
+
850
+ // 2) If current state dictates a certain behavior, follow that
839
851
840
852
// Notes relating to ignored diagnostics should also be ignored
841
- if (previousBehavior == Behavior::Ignore && isNote)
842
- return set (Behavior::Ignore);
853
+ if (previousBehavior == DiagnosticBehavior::Ignore
854
+ && lvl == DiagnosticBehavior::Note)
855
+ lvl = DiagnosticBehavior::Ignore;
843
856
844
857
// Suppress diagnostics when in a fatal state, except for follow-on notes
845
858
if (fatalErrorOccurred)
846
- if (!showDiagnosticsAfterFatalError && !isNote )
847
- return set (Behavior ::Ignore) ;
859
+ if (!showDiagnosticsAfterFatalError && lvl != DiagnosticBehavior::Note )
860
+ lvl = DiagnosticBehavior ::Ignore;
848
861
849
- // 2) If the user provided a behavior for this specific diagnostic, follow
850
- // that
862
+ // 3) If the user ignored this specific diagnostic, follow that
863
+ if (ignoredDiagnostics[(unsigned )diag.getID ()])
864
+ lvl = DiagnosticBehavior::Ignore;
851
865
852
- if (perDiagnosticBehavior[(unsigned )id] != Behavior::Unspecified)
853
- return set (perDiagnosticBehavior[(unsigned )id]);
854
-
855
- // 3) If the user provided a behavior for this diagnostic's kind, follow
856
- // that
857
- if (diagInfo.kind == DiagnosticKind::Warning) {
858
- if (suppressWarnings)
859
- return set (Behavior::Ignore);
866
+ // 4) If the user substituted a different behavior for this behavior, apply
867
+ // that change
868
+ if (lvl == DiagnosticBehavior::Warning) {
860
869
if (warningsAsErrors)
861
- return set (Behavior::Error);
870
+ lvl = DiagnosticBehavior::Error;
871
+ if (suppressWarnings)
872
+ lvl = DiagnosticBehavior::Ignore;
862
873
}
863
874
864
- // 4) Otherwise remap the diagnostic kind
865
- switch (diagInfo.kind ) {
866
- case DiagnosticKind::Note:
867
- return set (Behavior::Note);
868
- case DiagnosticKind::Error:
869
- return set (diagInfo.isFatal ? Behavior::Fatal : Behavior::Error);
870
- case DiagnosticKind::Warning:
871
- return set (Behavior::Warning);
872
- case DiagnosticKind::Remark:
873
- return set (Behavior::Remark);
875
+ // 5) Update current state for use during the next diagnostic
876
+ if (lvl == DiagnosticBehavior::Fatal) {
877
+ fatalErrorOccurred = true ;
878
+ anyErrorOccurred = true ;
879
+ } else if (lvl == DiagnosticBehavior::Error) {
880
+ anyErrorOccurred = true ;
874
881
}
875
882
876
- llvm_unreachable (" Unhandled DiagnosticKind in switch." );
883
+ assert ((!AssertOnError || !anyErrorOccurred) && " We emitted an error?!" );
884
+ assert ((!AssertOnWarning || (lvl != DiagnosticBehavior::Warning)) &&
885
+ " We emitted a warning?!" );
886
+
887
+ previousBehavior = lvl;
888
+ return lvl;
877
889
}
878
890
879
891
void DiagnosticEngine::flushActiveDiagnostic () {
@@ -910,8 +922,8 @@ static AccessLevel getBufferAccessLevel(const Decl *decl) {
910
922
911
923
Optional<DiagnosticInfo>
912
924
DiagnosticEngine::diagnosticInfoForDiagnostic (const Diagnostic &diagnostic) {
913
- auto behavior = state.determineBehavior (diagnostic. getID () );
914
- if (behavior == DiagnosticState::Behavior ::Ignore)
925
+ auto behavior = state.determineBehavior (diagnostic);
926
+ if (behavior == DiagnosticBehavior ::Ignore)
915
927
return None;
916
928
917
929
// Figure out the source location.
0 commit comments