28
28
#include " llvm/ADT/SmallString.h"
29
29
#include " llvm/ADT/Twine.h"
30
30
#include " llvm/Support/raw_ostream.h"
31
+
31
32
using namespace swift ;
32
33
34
+ namespace {
33
35
enum class DiagnosticOptions {
34
36
// / No options.
35
37
none,
@@ -46,29 +48,48 @@ enum class DiagnosticOptions {
46
48
Fatal,
47
49
};
48
50
49
- struct StoredDiagnosticInfo {
50
- // / \brief The kind of diagnostic we're dealing with.
51
- DiagnosticKind Kind;
52
-
53
- DiagnosticOptions Options;
51
+ // Reproduce the DiagIDs, as we want both the size and access to the raw ids
52
+ // themselves.
53
+ enum LocalDiagID : uint32_t {
54
+ #define DIAG (KIND, ID, Category, Options, Text, Signature ) ID,
55
+ #include " swift/AST/DiagnosticsAll.def"
56
+ NumDiags
57
+ };
58
+ }
54
59
55
- // FIXME: Category
56
-
57
- // / \brief Text associated with the diagnostic
58
- const char *Text;
60
+ static const char *DiagnosticStrings[] = {
61
+ #define ERROR (ID, Category, Options, Text, Signature ) Text,
62
+ #define WARNING (ID, Category, Options, Text, Signature ) Text,
63
+ #define NOTE (ID, Category, Options, Text, Signature ) Text,
64
+ #include " swift/AST/DiagnosticsAll.def"
65
+ " <not a diagnostic>" ,
59
66
};
60
67
61
- static StoredDiagnosticInfo StoredDiagnosticInfos [] = {
62
- #define ERROR (ID,Category,Options,Text,Signature ) \
63
- { DiagnosticKind::Error, DiagnosticOptions::Options, Text } ,
64
- #define WARNING (ID,Category,Options,Text,Signature ) \
65
- { DiagnosticKind::Warning, DiagnosticOptions::Options, Text } ,
66
- #define NOTE (ID,Category,Options,Text,Signature ) \
67
- { DiagnosticKind::Note, DiagnosticOptions::Options, Text } ,
68
+ static bool DiagnosticPointsToFirstBadToken [] = {
69
+ #define ERROR (ID, Category, Options, Text, Signature ) \
70
+ DiagnosticOptions::Options == DiagnosticOptions::PointsToFirstBadToken ,
71
+ #define WARNING (ID, Category, Options, Text, Signature ) \
72
+ DiagnosticOptions::Options == DiagnosticOptions::PointsToFirstBadToken ,
73
+ #define NOTE (ID, Category, Options, Text, Signature ) \
74
+ DiagnosticOptions::Options == DiagnosticOptions::PointsToFirstBadToken ,
68
75
#include " swift/AST/DiagnosticsAll.def"
69
- { DiagnosticKind::Error, DiagnosticOptions::none, " <not a diagnostic>" }
76
+ " <not a diagnostic>" ,
70
77
};
71
78
79
+ DiagnosticState::DiagnosticState () {
80
+ // Initialize our per-diagnostic state to the default
81
+ perDiagnosticState.resize (LocalDiagID::NumDiags);
82
+ #define ERROR (ID, Category, Options, Text, Signature ) \
83
+ perDiagnosticState[LocalDiagID::ID] = \
84
+ DiagnosticOptions::Options == DiagnosticOptions::Fatal ? Behavior::Fatal \
85
+ : Behavior::Err;
86
+ #define WARNING (ID, Category, Options, Text, Signature ) \
87
+ perDiagnosticState[LocalDiagID::ID] = Behavior::Warn;
88
+ #define NOTE (ID, Category, Options, Text, Signature ) \
89
+ perDiagnosticState[LocalDiagID::ID] = Behavior::Note;
90
+ #include " swift/AST/DiagnosticsAll.def"
91
+ }
92
+
72
93
static CharSourceRange toCharSourceRange (SourceManager &SM, SourceRange SR) {
73
94
return CharSourceRange (SM, SR.Start , Lexer::getLocForEndOfToken (SM, SR.End ));
74
95
}
@@ -175,15 +196,7 @@ void InFlightDiagnostic::flush() {
175
196
}
176
197
177
198
bool DiagnosticEngine::isDiagnosticPointsToFirstBadToken (DiagID ID) const {
178
- const StoredDiagnosticInfo &StoredInfo =
179
- StoredDiagnosticInfos[(unsigned ) ID];
180
- return StoredInfo.Options == DiagnosticOptions::PointsToFirstBadToken;
181
- }
182
-
183
- bool DiagnosticState::isDiagnosticFatal (DiagID ID) const {
184
- const StoredDiagnosticInfo &StoredInfo =
185
- StoredDiagnosticInfos[(unsigned ) ID];
186
- return StoredInfo.Options == DiagnosticOptions::Fatal;
199
+ return DiagnosticPointsToFirstBadToken[(unsigned )ID];
187
200
}
188
201
189
202
// / \brief Skip forward to one of the given delimiters.
@@ -443,13 +456,29 @@ static void formatDiagnosticText(StringRef InText,
443
456
(void )Result;
444
457
assert (ArgIndex < Args.size () && " Out-of-range argument index" );
445
458
InText = InText.substr (Length);
446
-
459
+
447
460
// Convert the argument to a string.
448
461
formatDiagnosticArgument (Modifier, ModifierArguments, Args, ArgIndex, Out);
449
462
}
450
463
}
451
464
452
- DiagnosticState::Behavior DiagnosticState::getBehavior (const Diagnostic &diag) {
465
+ static DiagnosticKind toDiagnosticKind (DiagnosticState::Behavior behavior) {
466
+ switch (behavior) {
467
+ case DiagnosticState::Behavior::Unspecified:
468
+ llvm_unreachable (" unspecified behavior" );
469
+ case DiagnosticState::Behavior::Ignore:
470
+ llvm_unreachable (" trying to map an ignored diagnostic" );
471
+ case DiagnosticState::Behavior::Err:
472
+ case DiagnosticState::Behavior::Fatal:
473
+ return DiagnosticKind::Error;
474
+ case DiagnosticState::Behavior::Note:
475
+ return DiagnosticKind::Note;
476
+ case DiagnosticState::Behavior::Warn:
477
+ return DiagnosticKind::Warning;
478
+ }
479
+ }
480
+
481
+ DiagnosticState::Behavior DiagnosticState::determineBehavior (DiagID id) {
453
482
auto set = [this ](DiagnosticState::Behavior lvl) {
454
483
if (lvl == Behavior::Fatal) {
455
484
fatalErrorOccurred = true ;
@@ -462,33 +491,26 @@ DiagnosticState::Behavior DiagnosticState::getBehavior(const Diagnostic &diag) {
462
491
return lvl;
463
492
};
464
493
465
- auto diagKind = StoredDiagnosticInfos [(unsigned )diag. getID ()]. Kind ;
494
+ auto behavior = perDiagnosticState [(unsigned )id] ;
466
495
467
496
// Notes relating to ignored diagnostics should also be ignored
468
- if (previousBehavior == Behavior::Ignore && diagKind == DiagnosticKind ::Note)
497
+ if (previousBehavior == Behavior::Ignore && behavior == Behavior ::Note)
469
498
return set (Behavior::Ignore);
470
499
471
500
// Suppress diagnostics when in a fatal state, except for follow-on notes
472
501
// about the original fatal diag
473
502
if (fatalErrorOccurred) {
474
503
bool emitAnyways = showDiagnosticsAfterFatalError ||
475
- (diagKind == DiagnosticKind ::Note &&
504
+ (behavior == Behavior ::Note &&
476
505
previousBehavior != Behavior::Ignore);
477
506
if (!emitAnyways)
478
507
return set (Behavior::Ignore);
479
- } else if (isDiagnosticFatal (diag.getID ())) {
480
- return set (Behavior::Fatal);
481
508
}
482
509
483
- // Re-map as appropriate
484
- switch (diagKind) {
485
- case DiagnosticKind::Error:
486
- return set (Behavior::Err);
487
- case DiagnosticKind::Warning:
488
- return set (ignoreAllWarnings ? Behavior::Ignore : Behavior::Warn);
489
- case DiagnosticKind::Note:
490
- return set (Behavior::Note);
491
- }
510
+ if (behavior == Behavior::Warn && ignoreAllWarnings)
511
+ return set (Behavior::Ignore);
512
+
513
+ return set (behavior);
492
514
}
493
515
494
516
void DiagnosticEngine::flushActiveDiagnostic () {
@@ -509,13 +531,10 @@ void DiagnosticEngine::emitTentativeDiagnostics() {
509
531
}
510
532
511
533
void DiagnosticEngine::emitDiagnostic (const Diagnostic &diagnostic) {
512
- auto behavior = state.getBehavior (diagnostic);
534
+ auto behavior = state.determineBehavior (diagnostic. getID () );
513
535
if (behavior == DiagnosticState::Behavior::Ignore)
514
536
return ;
515
537
516
- const StoredDiagnosticInfo &StoredInfo
517
- = StoredDiagnosticInfos[(unsigned )diagnostic.getID ()];
518
-
519
538
// Figure out the source location.
520
539
SourceLoc loc = diagnostic.getLoc ();
521
540
if (loc.isInvalid () && diagnostic.getDecl ()) {
@@ -634,7 +653,7 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
634
653
llvm::SmallString<256 > Text;
635
654
{
636
655
llvm::raw_svector_ostream Out (Text);
637
- formatDiagnosticText (StoredInfo. Text , diagnostic.getArgs (), Out);
656
+ formatDiagnosticText (DiagnosticStrings[( unsigned )diagnostic. getID ()] , diagnostic.getArgs (), Out);
638
657
}
639
658
640
659
// Pass the diagnostic off to the consumer.
@@ -643,7 +662,7 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
643
662
Info.Ranges = diagnostic.getRanges ();
644
663
Info.FixIts = diagnostic.getFixIts ();
645
664
for (auto &Consumer : Consumers) {
646
- Consumer->handleDiagnostic (SourceMgr, loc, StoredInfo. Kind , Text, Info);
665
+ Consumer->handleDiagnostic (SourceMgr, loc, toDiagnosticKind (behavior) , Text, Info);
647
666
}
648
667
}
649
668
0 commit comments