summaryrefslogtreecommitdiffstats
path: root/lib/Frontend/VerifyDiagnosticConsumer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/VerifyDiagnosticConsumer.cpp')
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp90
1 files changed, 69 insertions, 21 deletions
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 82f6e91..46745b6 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -111,8 +111,13 @@ void VerifyDiagnosticConsumer::EndSourceFile() {
void VerifyDiagnosticConsumer::HandleDiagnostic(
DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
- if (Info.hasSourceManager())
+ if (Info.hasSourceManager()) {
+ // If this diagnostic is for a different source manager, ignore it.
+ if (SrcManager && &Info.getSourceManager() != SrcManager)
+ return;
+
setSourceManager(Info.getSourceManager());
+ }
#ifndef NDEBUG
// Debug build tracks unparsed files for possible
@@ -278,8 +283,10 @@ private:
///
/// Returns true if any valid directives were found.
static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
- SourceLocation Pos, DiagnosticsEngine &Diags,
+ Preprocessor *PP, SourceLocation Pos,
VerifyDiagnosticConsumer::DirectiveStatus &Status) {
+ DiagnosticsEngine &Diags = PP ? PP->getDiagnostics() : SM.getDiagnostics();
+
// A single comment may contain multiple directives.
bool FoundDirective = false;
for (ParseHelper PH(S); !PH.Done();) {
@@ -353,10 +360,30 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
else ExpectedLine -= Line;
ExpectedLoc = SM.translateLineCol(SM.getFileID(Pos), ExpectedLine, 1);
}
- } else {
+ } else if (PH.Next(Line)) {
// Absolute line number.
- if (PH.Next(Line) && Line > 0)
+ if (Line > 0)
ExpectedLoc = SM.translateLineCol(SM.getFileID(Pos), Line, 1);
+ } else if (PP && PH.Search(":")) {
+ // Specific source file.
+ StringRef Filename(PH.C, PH.P-PH.C);
+ PH.Advance();
+
+ // Lookup file via Preprocessor, like a #include.
+ const DirectoryLookup *CurDir;
+ const FileEntry *FE = PP->LookupFile(Filename, false, NULL, CurDir,
+ NULL, NULL, 0);
+ if (!FE) {
+ Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
+ diag::err_verify_missing_file) << Filename << KindStr;
+ continue;
+ }
+
+ if (SM.translateFile(FE).isInvalid())
+ SM.createFileID(FE, Pos, SrcMgr::C_User);
+
+ if (PH.Next(Line) && Line > 0)
+ ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
}
if (ExpectedLoc.isInvalid()) {
@@ -454,6 +481,11 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
SourceRange Comment) {
SourceManager &SM = PP.getSourceManager();
+
+ // If this comment is for a different source manager, ignore it.
+ if (SrcManager && &SM != SrcManager)
+ return false;
+
SourceLocation CommentBegin = Comment.getBegin();
const char *CommentRaw = SM.getCharacterData(CommentBegin);
@@ -465,7 +497,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
// Fold any "\<EOL>" sequences
size_t loc = C.find('\\');
if (loc == StringRef::npos) {
- ParseDirective(C, &ED, SM, CommentBegin, PP.getDiagnostics(), Status);
+ ParseDirective(C, &ED, SM, &PP, CommentBegin, Status);
return false;
}
@@ -495,7 +527,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
}
if (!C2.empty())
- ParseDirective(C2, &ED, SM, CommentBegin, PP.getDiagnostics(), Status);
+ ParseDirective(C2, &ED, SM, &PP, CommentBegin, Status);
return false;
}
@@ -530,8 +562,7 @@ static bool findDirectives(SourceManager &SM, FileID FID,
if (Comment.empty()) continue;
// Find first directive.
- if (ParseDirective(Comment, 0, SM, Tok.getLocation(),
- SM.getDiagnostics(), Status))
+ if (ParseDirective(Comment, 0, SM, 0, Tok.getLocation(), Status))
return true;
}
return false;
@@ -551,8 +582,13 @@ static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceM
for (const_diag_iterator I = diag_begin, E = diag_end; I != E; ++I) {
if (I->first.isInvalid() || !SourceMgr)
OS << "\n (frontend)";
- else
- OS << "\n Line " << SourceMgr->getPresumedLineNumber(I->first);
+ else {
+ OS << "\n ";
+ if (const FileEntry *File = SourceMgr->getFileEntryForID(
+ SourceMgr->getFileID(I->first)))
+ OS << " File " << File->getName();
+ OS << " Line " << SourceMgr->getPresumedLineNumber(I->first);
+ }
OS << ": " << I->second;
}
@@ -572,11 +608,12 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager &SourceMgr
llvm::raw_svector_ostream OS(Fmt);
for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
Directive &D = **I;
- OS << "\n Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
+ OS << "\n File " << SourceMgr.getFilename(D.DiagnosticLoc)
+ << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
if (D.DirectiveLoc != D.DiagnosticLoc)
OS << " (directive at "
- << SourceMgr.getFilename(D.DirectiveLoc) << ":"
- << SourceMgr.getPresumedLineNumber(D.DirectiveLoc) << ")";
+ << SourceMgr.getFilename(D.DirectiveLoc) << ':'
+ << SourceMgr.getPresumedLineNumber(D.DirectiveLoc) << ')';
OS << ": " << D.Text;
}
@@ -585,6 +622,22 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager &SourceMgr
return DL.size();
}
+/// \brief Determine whether two source locations come from the same file.
+static bool IsFromSameFile(SourceManager &SM, SourceLocation DirectiveLoc,
+ SourceLocation DiagnosticLoc) {
+ while (DiagnosticLoc.isMacroID())
+ DiagnosticLoc = SM.getImmediateMacroCallerLoc(DiagnosticLoc);
+
+ if (SM.isFromSameFile(DirectiveLoc, DiagnosticLoc))
+ return true;
+
+ const FileEntry *DiagFile = SM.getFileEntryForID(SM.getFileID(DiagnosticLoc));
+ if (!DiagFile && SM.isFromMainFile(DirectiveLoc))
+ return true;
+
+ return (DiagFile == SM.getFileEntryForID(SM.getFileID(DirectiveLoc)));
+}
+
/// CheckLists - Compare expected to seen diagnostic lists and return the
/// the difference between them.
///
@@ -607,6 +660,9 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
if (LineNo1 != LineNo2)
continue;
+ if (!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
+ continue;
+
const std::string &RightText = II->second;
if (D.match(RightText))
break;
@@ -764,14 +820,6 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() {
ED.Notes.clear();
}
-DiagnosticConsumer *
-VerifyDiagnosticConsumer::clone(DiagnosticsEngine &Diags) const {
- if (!Diags.getClient())
- Diags.setClient(PrimaryClient->clone(Diags));
-
- return new VerifyDiagnosticConsumer(Diags);
-}
-
Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
SourceLocation DiagnosticLoc, StringRef Text,
unsigned Min, unsigned Max) {
OpenPOWER on IntegriCloud