@@ -89,9 +89,10 @@ namespace {
89
89
class StandardDirective : public Directive {
90
90
public:
91
91
StandardDirective (SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
92
- bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
93
- unsigned Min, unsigned Max)
94
- : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine,
92
+ StringRef Spelling, bool MatchAnyFileAndLine,
93
+ bool MatchAnyLine, StringRef Text, unsigned Min,
94
+ unsigned Max)
95
+ : Directive(DirectiveLoc, DiagnosticLoc, Spelling, MatchAnyFileAndLine,
95
96
MatchAnyLine, Text, Min, Max) {}
96
97
97
98
bool isValid (std::string &Error) override {
@@ -106,9 +107,10 @@ class StandardDirective : public Directive {
106
107
class RegexDirective : public Directive {
107
108
public:
108
109
RegexDirective (SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
109
- bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
110
- unsigned Min, unsigned Max, StringRef RegexStr)
111
- : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyFileAndLine,
110
+ StringRef Spelling, bool MatchAnyFileAndLine,
111
+ bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
112
+ StringRef RegexStr)
113
+ : Directive(DirectiveLoc, DiagnosticLoc, Spelling, MatchAnyFileAndLine,
112
114
MatchAnyLine, Text, Min, Max),
113
115
Regex (RegexStr) {}
114
116
@@ -285,6 +287,7 @@ class ParseHelper
285
287
// The information necessary to create a directive.
286
288
struct UnattachedDirective {
287
289
DirectiveList *DL = nullptr ;
290
+ std::string Spelling;
288
291
bool RegexKind = false ;
289
292
SourceLocation DirectivePos, ContentBegin;
290
293
std::string Text;
@@ -299,8 +302,8 @@ void attachDirective(DiagnosticsEngine &Diags, const UnattachedDirective &UD,
299
302
bool MatchAnyLine = false ) {
300
303
// Construct new directive.
301
304
std::unique_ptr<Directive> D = Directive::create (
302
- UD.RegexKind , UD.DirectivePos , ExpectedLoc, MatchAnyFileAndLine ,
303
- MatchAnyLine, UD.Text , UD.Min , UD.Max );
305
+ UD.RegexKind , UD.DirectivePos , ExpectedLoc, UD. Spelling ,
306
+ MatchAnyFileAndLine, MatchAnyLine, UD.Text , UD.Min , UD.Max );
304
307
305
308
std::string Error;
306
309
if (!D->isValid (Error)) {
@@ -408,7 +411,7 @@ static std::string DetailedErrorString(const DiagnosticsEngine &Diags) {
408
411
// / Returns true if any valid directives were found.
409
412
static bool ParseDirective (StringRef S, ExpectedData *ED, SourceManager &SM,
410
413
Preprocessor *PP, SourceLocation Pos,
411
- VerifyDiagnosticConsumer::DirectiveStatus &Status ,
414
+ VerifyDiagnosticConsumer::ParsingState &State ,
412
415
VerifyDiagnosticConsumer::MarkerTracker &Markers) {
413
416
DiagnosticsEngine &Diags = PP ? PP->getDiagnostics () : SM.getDiagnostics ();
414
417
@@ -440,8 +443,9 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
440
443
StringRef DToken = PH.Match ();
441
444
PH.Advance ();
442
445
443
- // Default directive kind.
444
446
UnattachedDirective D;
447
+ D.Spelling = DToken;
448
+ // Default directive kind.
445
449
const char *KindStr = " string" ;
446
450
447
451
// Parse the initial directive token in reverse so we can easily determine
@@ -482,19 +486,24 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
482
486
continue ;
483
487
484
488
if (NoDiag) {
485
- if (Status == VerifyDiagnosticConsumer::HasOtherExpectedDirectives)
489
+ if (State.Status ==
490
+ VerifyDiagnosticConsumer::HasOtherExpectedDirectives) {
486
491
Diags.Report (Pos, diag::err_verify_invalid_no_diags)
487
- << DetailedErrorString (Diags) << /* IsExpectedNoDiagnostics=*/ true ;
488
- else
489
- Status = VerifyDiagnosticConsumer::HasExpectedNoDiagnostics;
492
+ << D.Spelling << /* IsExpectedNoDiagnostics=*/ true ;
493
+ } else if (State.Status !=
494
+ VerifyDiagnosticConsumer::HasExpectedNoDiagnostics) {
495
+ State.Status = VerifyDiagnosticConsumer::HasExpectedNoDiagnostics;
496
+ State.FirstNoDiagnosticsDirective = D.Spelling ;
497
+ }
490
498
continue ;
491
499
}
492
- if (Status == VerifyDiagnosticConsumer::HasExpectedNoDiagnostics) {
500
+ if (State. Status == VerifyDiagnosticConsumer::HasExpectedNoDiagnostics) {
493
501
Diags.Report (Pos, diag::err_verify_invalid_no_diags)
494
- << DetailedErrorString (Diags) << /* IsExpectedNoDiagnostics=*/ false ;
502
+ << D.Spelling << /* IsExpectedNoDiagnostics=*/ false
503
+ << State.FirstNoDiagnosticsDirective ;
495
504
continue ;
496
505
}
497
- Status = VerifyDiagnosticConsumer::HasOtherExpectedDirectives;
506
+ State. Status = VerifyDiagnosticConsumer::HasOtherExpectedDirectives;
498
507
499
508
// If a directive has been found but we're not interested
500
509
// in storing the directive information, return now.
@@ -670,7 +679,7 @@ VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_)
670
679
: Diags(Diags_), PrimaryClient(Diags.getClient()),
671
680
PrimaryClientOwner(Diags.takeClient()),
672
681
Buffer(new TextDiagnosticBuffer()), Markers(new MarkerTracker(Diags)),
673
- Status( HasNoDirectives) {
682
+ State{ HasNoDirectives, {}} {
674
683
if (Diags.hasSourceManager ())
675
684
setSourceManager (Diags.getSourceManager ());
676
685
}
@@ -788,7 +797,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
788
797
// Fold any "\<EOL>" sequences
789
798
size_t loc = C.find (' \\ ' );
790
799
if (loc == StringRef::npos) {
791
- ParseDirective (C, &ED, SM, &PP, CommentBegin, Status , *Markers);
800
+ ParseDirective (C, &ED, SM, &PP, CommentBegin, State , *Markers);
792
801
return false ;
793
802
}
794
803
@@ -818,7 +827,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
818
827
}
819
828
820
829
if (!C2.empty ())
821
- ParseDirective (C2, &ED, SM, &PP, CommentBegin, Status , *Markers);
830
+ ParseDirective (C2, &ED, SM, &PP, CommentBegin, State , *Markers);
822
831
return false ;
823
832
}
824
833
@@ -843,8 +852,8 @@ static bool findDirectives(SourceManager &SM, FileID FID,
843
852
844
853
Token Tok;
845
854
Tok.setKind (tok::comment);
846
- VerifyDiagnosticConsumer::DirectiveStatus Status =
847
- VerifyDiagnosticConsumer::HasNoDirectives;
855
+ VerifyDiagnosticConsumer::ParsingState State = {
856
+ VerifyDiagnosticConsumer::HasNoDirectives, {}} ;
848
857
while (Tok.isNot (tok::eof)) {
849
858
RawLex.LexFromRawLexer (Tok);
850
859
if (!Tok.is (tok::comment)) continue ;
@@ -856,8 +865,8 @@ static bool findDirectives(SourceManager &SM, FileID FID,
856
865
VerifyDiagnosticConsumer::MarkerTracker Markers (SM.getDiagnostics ());
857
866
858
867
// Find first directive.
859
- if (ParseDirective (Comment, nullptr , SM, nullptr , Tok.getLocation (),
860
- Status, Markers))
868
+ if (ParseDirective (Comment, nullptr , SM, nullptr , Tok.getLocation (), State,
869
+ Markers))
861
870
return true ;
862
871
}
863
872
return false ;
@@ -887,10 +896,11 @@ static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceM
887
896
OS << " : " << I->second ;
888
897
}
889
898
899
+ const bool IsSinglePrefix =
900
+ Diags.getDiagnosticOptions ().VerifyPrefixes .size () == 1 ;
890
901
std::string Prefix = *Diags.getDiagnosticOptions ().VerifyPrefixes .begin ();
891
- std::string KindStr = Prefix + " -" + Kind;
892
902
Diags.Report (diag::err_verify_inconsistent_diags).setForceEmit ()
893
- << KindStr << /* Unexpected=*/ true << OS.str ();
903
+ << IsSinglePrefix << Prefix << Kind << /* Unexpected=*/ true << OS.str ();
894
904
return std::distance (diag_begin, diag_end);
895
905
}
896
906
@@ -902,6 +912,9 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
902
912
if (DL.empty ())
903
913
return 0 ;
904
914
915
+ const bool IsSinglePrefix =
916
+ Diags.getDiagnosticOptions ().VerifyPrefixes .size () == 1 ;
917
+
905
918
SmallString<256 > Fmt;
906
919
llvm::raw_svector_ostream OS (Fmt);
907
920
for (const auto *D : DL) {
@@ -917,13 +930,14 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
917
930
OS << " (directive at "
918
931
<< SourceMgr.getFilename (D->DirectiveLoc ) << ' :'
919
932
<< SourceMgr.getPresumedLineNumber (D->DirectiveLoc ) << ' )' ;
933
+ if (!IsSinglePrefix)
934
+ OS << " \' " << D->Spelling << ' \' ' ;
920
935
OS << " : " << D->Text ;
921
936
}
922
937
923
938
std::string Prefix = *Diags.getDiagnosticOptions ().VerifyPrefixes .begin ();
924
- std::string KindStr = Prefix + " -" + Kind;
925
939
Diags.Report (diag::err_verify_inconsistent_diags).setForceEmit ()
926
- << KindStr << /* Unexpected=*/ false << OS.str ();
940
+ << IsSinglePrefix << Prefix << Kind << /* Unexpected=*/ false << OS.str ();
927
941
return DL.size ();
928
942
}
929
943
@@ -1109,11 +1123,11 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() {
1109
1123
if (SrcManager) {
1110
1124
// Produce an error if no expected-* directives could be found in the
1111
1125
// source file(s) processed.
1112
- if (Status == HasNoDirectives) {
1126
+ if (State. Status == HasNoDirectives) {
1113
1127
Diags.Report (diag::err_verify_no_directives).setForceEmit ()
1114
1128
<< DetailedErrorString (Diags);
1115
1129
++NumErrors;
1116
- Status = HasNoDirectivesReported;
1130
+ State. Status = HasNoDirectivesReported;
1117
1131
}
1118
1132
1119
1133
// Check that the expected diagnostics occurred.
@@ -1142,15 +1156,14 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() {
1142
1156
ED.Reset ();
1143
1157
}
1144
1158
1145
- std::unique_ptr<Directive> Directive::create (bool RegexKind,
1146
- SourceLocation DirectiveLoc,
1147
- SourceLocation DiagnosticLoc,
1148
- bool MatchAnyFileAndLine,
1149
- bool MatchAnyLine, StringRef Text,
1150
- unsigned Min, unsigned Max) {
1159
+ std::unique_ptr<Directive>
1160
+ Directive::create (bool RegexKind, SourceLocation DirectiveLoc,
1161
+ SourceLocation DiagnosticLoc, StringRef Spelling,
1162
+ bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text,
1163
+ unsigned Min, unsigned Max) {
1151
1164
if (!RegexKind)
1152
1165
return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc,
1153
- MatchAnyFileAndLine,
1166
+ Spelling, MatchAnyFileAndLine,
1154
1167
MatchAnyLine, Text, Min, Max);
1155
1168
1156
1169
// Parse the directive into a regular expression.
@@ -1175,7 +1188,7 @@ std::unique_ptr<Directive> Directive::create(bool RegexKind,
1175
1188
}
1176
1189
}
1177
1190
1178
- return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc,
1191
+ return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc, Spelling,
1179
1192
MatchAnyFileAndLine, MatchAnyLine,
1180
1193
Text, Min, Max, RegexStr);
1181
1194
}
0 commit comments