@@ -89,9 +89,10 @@ namespace {
8989class StandardDirective : public Directive {
9090public:
9191 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,
9596 MatchAnyLine, Text, Min, Max) {}
9697
9798 bool isValid (std::string &Error) override {
@@ -106,9 +107,10 @@ class StandardDirective : public Directive {
106107class RegexDirective : public Directive {
107108public:
108109 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,
112114 MatchAnyLine, Text, Min, Max),
113115 Regex (RegexStr) {}
114116
@@ -285,6 +287,7 @@ class ParseHelper
285287// The information necessary to create a directive.
286288struct UnattachedDirective {
287289 DirectiveList *DL = nullptr ;
290+ std::string Spelling;
288291 bool RegexKind = false ;
289292 SourceLocation DirectivePos, ContentBegin;
290293 std::string Text;
@@ -299,8 +302,8 @@ void attachDirective(DiagnosticsEngine &Diags, const UnattachedDirective &UD,
299302 bool MatchAnyLine = false ) {
300303 // Construct new directive.
301304 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 );
304307
305308 std::string Error;
306309 if (!D->isValid (Error)) {
@@ -408,7 +411,7 @@ static std::string DetailedErrorString(const DiagnosticsEngine &Diags) {
408411// / Returns true if any valid directives were found.
409412static bool ParseDirective (StringRef S, ExpectedData *ED, SourceManager &SM,
410413 Preprocessor *PP, SourceLocation Pos,
411- VerifyDiagnosticConsumer::DirectiveStatus &Status ,
414+ VerifyDiagnosticConsumer::ParsingState &State ,
412415 VerifyDiagnosticConsumer::MarkerTracker &Markers) {
413416 DiagnosticsEngine &Diags = PP ? PP->getDiagnostics () : SM.getDiagnostics ();
414417
@@ -440,8 +443,9 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
440443 StringRef DToken = PH.Match ();
441444 PH.Advance ();
442445
443- // Default directive kind.
444446 UnattachedDirective D;
447+ D.Spelling = DToken;
448+ // Default directive kind.
445449 const char *KindStr = " string" ;
446450
447451 // 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,
482486 continue ;
483487
484488 if (NoDiag) {
485- if (Status == VerifyDiagnosticConsumer::HasOtherExpectedDirectives)
489+ if (State.Status ==
490+ VerifyDiagnosticConsumer::HasOtherExpectedDirectives) {
486491 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+ }
490498 continue ;
491499 }
492- if (Status == VerifyDiagnosticConsumer::HasExpectedNoDiagnostics) {
500+ if (State. Status == VerifyDiagnosticConsumer::HasExpectedNoDiagnostics) {
493501 Diags.Report (Pos, diag::err_verify_invalid_no_diags)
494- << DetailedErrorString (Diags) << /* IsExpectedNoDiagnostics=*/ false ;
502+ << D.Spelling << /* IsExpectedNoDiagnostics=*/ false
503+ << State.FirstNoDiagnosticsDirective ;
495504 continue ;
496505 }
497- Status = VerifyDiagnosticConsumer::HasOtherExpectedDirectives;
506+ State. Status = VerifyDiagnosticConsumer::HasOtherExpectedDirectives;
498507
499508 // If a directive has been found but we're not interested
500509 // in storing the directive information, return now.
@@ -670,7 +679,7 @@ VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_)
670679 : Diags(Diags_), PrimaryClient(Diags.getClient()),
671680 PrimaryClientOwner(Diags.takeClient()),
672681 Buffer(new TextDiagnosticBuffer()), Markers(new MarkerTracker(Diags)),
673- Status( HasNoDirectives) {
682+ State{ HasNoDirectives, {}} {
674683 if (Diags.hasSourceManager ())
675684 setSourceManager (Diags.getSourceManager ());
676685}
@@ -788,7 +797,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
788797 // Fold any "\<EOL>" sequences
789798 size_t loc = C.find (' \\ ' );
790799 if (loc == StringRef::npos) {
791- ParseDirective (C, &ED, SM, &PP, CommentBegin, Status , *Markers);
800+ ParseDirective (C, &ED, SM, &PP, CommentBegin, State , *Markers);
792801 return false ;
793802 }
794803
@@ -818,7 +827,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
818827 }
819828
820829 if (!C2.empty ())
821- ParseDirective (C2, &ED, SM, &PP, CommentBegin, Status , *Markers);
830+ ParseDirective (C2, &ED, SM, &PP, CommentBegin, State , *Markers);
822831 return false ;
823832}
824833
@@ -843,8 +852,8 @@ static bool findDirectives(SourceManager &SM, FileID FID,
843852
844853 Token Tok;
845854 Tok.setKind (tok::comment);
846- VerifyDiagnosticConsumer::DirectiveStatus Status =
847- VerifyDiagnosticConsumer::HasNoDirectives;
855+ VerifyDiagnosticConsumer::ParsingState State = {
856+ VerifyDiagnosticConsumer::HasNoDirectives, {}} ;
848857 while (Tok.isNot (tok::eof)) {
849858 RawLex.LexFromRawLexer (Tok);
850859 if (!Tok.is (tok::comment)) continue ;
@@ -856,8 +865,8 @@ static bool findDirectives(SourceManager &SM, FileID FID,
856865 VerifyDiagnosticConsumer::MarkerTracker Markers (SM.getDiagnostics ());
857866
858867 // 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))
861870 return true ;
862871 }
863872 return false ;
@@ -887,10 +896,11 @@ static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceM
887896 OS << " : " << I->second ;
888897 }
889898
899+ const bool IsSinglePrefix =
900+ Diags.getDiagnosticOptions ().VerifyPrefixes .size () == 1 ;
890901 std::string Prefix = *Diags.getDiagnosticOptions ().VerifyPrefixes .begin ();
891- std::string KindStr = Prefix + " -" + Kind;
892902 Diags.Report (diag::err_verify_inconsistent_diags).setForceEmit ()
893- << KindStr << /* Unexpected=*/ true << OS.str ();
903+ << IsSinglePrefix << Prefix << Kind << /* Unexpected=*/ true << OS.str ();
894904 return std::distance (diag_begin, diag_end);
895905}
896906
@@ -902,6 +912,9 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
902912 if (DL.empty ())
903913 return 0 ;
904914
915+ const bool IsSinglePrefix =
916+ Diags.getDiagnosticOptions ().VerifyPrefixes .size () == 1 ;
917+
905918 SmallString<256 > Fmt;
906919 llvm::raw_svector_ostream OS (Fmt);
907920 for (const auto *D : DL) {
@@ -917,13 +930,14 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
917930 OS << " (directive at "
918931 << SourceMgr.getFilename (D->DirectiveLoc ) << ' :'
919932 << SourceMgr.getPresumedLineNumber (D->DirectiveLoc ) << ' )' ;
933+ if (!IsSinglePrefix)
934+ OS << " \' " << D->Spelling << ' \' ' ;
920935 OS << " : " << D->Text ;
921936 }
922937
923938 std::string Prefix = *Diags.getDiagnosticOptions ().VerifyPrefixes .begin ();
924- std::string KindStr = Prefix + " -" + Kind;
925939 Diags.Report (diag::err_verify_inconsistent_diags).setForceEmit ()
926- << KindStr << /* Unexpected=*/ false << OS.str ();
940+ << IsSinglePrefix << Prefix << Kind << /* Unexpected=*/ false << OS.str ();
927941 return DL.size ();
928942}
929943
@@ -1109,11 +1123,11 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() {
11091123 if (SrcManager) {
11101124 // Produce an error if no expected-* directives could be found in the
11111125 // source file(s) processed.
1112- if (Status == HasNoDirectives) {
1126+ if (State. Status == HasNoDirectives) {
11131127 Diags.Report (diag::err_verify_no_directives).setForceEmit ()
11141128 << DetailedErrorString (Diags);
11151129 ++NumErrors;
1116- Status = HasNoDirectivesReported;
1130+ State. Status = HasNoDirectivesReported;
11171131 }
11181132
11191133 // Check that the expected diagnostics occurred.
@@ -1142,15 +1156,14 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() {
11421156 ED.Reset ();
11431157}
11441158
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) {
11511164 if (!RegexKind)
11521165 return std::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc,
1153- MatchAnyFileAndLine,
1166+ Spelling, MatchAnyFileAndLine,
11541167 MatchAnyLine, Text, Min, Max);
11551168
11561169 // Parse the directive into a regular expression.
@@ -1175,7 +1188,7 @@ std::unique_ptr<Directive> Directive::create(bool RegexKind,
11751188 }
11761189 }
11771190
1178- return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc,
1191+ return std::make_unique<RegexDirective>(DirectiveLoc, DiagnosticLoc, Spelling,
11791192 MatchAnyFileAndLine, MatchAnyLine,
11801193 Text, Min, Max, RegexStr);
11811194}
0 commit comments