diff options
Diffstat (limited to 'lib/Frontend/VerifyDiagnosticConsumer.cpp')
-rw-r--r-- | lib/Frontend/VerifyDiagnosticConsumer.cpp | 90 |
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) { |