diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | dbe13110f59f48b4dbb7552b3ac2935acdeece7f (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | |
parent | 9da628931ebf2609493570f87824ca22402cc65f (diff) |
Vendor import of clang trunk r154661:vendor/clang/clang-trunk-r154661
Notes
Notes:
svn path=/vendor/clang/dist/; revision=234287
svn path=/vendor/clang/clang-trunk-r154661/; revision=234288; tag=vendor/clang/clang-trunk-r154661
Diffstat (limited to 'lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | 127 |
1 files changed, 62 insertions, 65 deletions
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index 0c4e4277e4d6..629f1eab4356 100644 --- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -39,15 +39,13 @@ class HTMLDiagnostics : public PathDiagnosticConsumer { llvm::sys::Path Directory, FilePrefix; bool createdDir, noDir; const Preprocessor &PP; - std::vector<const PathDiagnostic*> BatchedDiags; public: HTMLDiagnostics(const std::string& prefix, const Preprocessor &pp); virtual ~HTMLDiagnostics() { FlushDiagnostics(NULL); } - virtual void FlushDiagnostics(SmallVectorImpl<std::string> *FilesMade); - - virtual void HandlePathDiagnosticImpl(const PathDiagnostic* D); + virtual void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags, + SmallVectorImpl<std::string> *FilesMade); virtual StringRef getName() const { return "HTMLDiagnostics"; @@ -88,34 +86,49 @@ ento::createHTMLDiagnosticConsumer(const std::string& prefix, // Report processing. //===----------------------------------------------------------------------===// -void HTMLDiagnostics::HandlePathDiagnosticImpl(const PathDiagnostic* D) { - if (!D) - return; - - if (D->empty()) { - delete D; - return; +void HTMLDiagnostics::FlushDiagnosticsImpl( + std::vector<const PathDiagnostic *> &Diags, + SmallVectorImpl<std::string> *FilesMade) { + for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(), + et = Diags.end(); it != et; ++it) { + ReportDiag(**it, FilesMade); } - - const_cast<PathDiagnostic*>(D)->flattenLocations(); - BatchedDiags.push_back(D); } -void -HTMLDiagnostics::FlushDiagnostics(SmallVectorImpl<std::string> *FilesMade) -{ - while (!BatchedDiags.empty()) { - const PathDiagnostic* D = BatchedDiags.back(); - BatchedDiags.pop_back(); - ReportDiag(*D, FilesMade); - delete D; +static void flattenPath(PathPieces &primaryPath, PathPieces ¤tPath, + const PathPieces &oldPath) { + for (PathPieces::const_iterator it = oldPath.begin(), et = oldPath.end(); + it != et; ++it ) { + PathDiagnosticPiece *piece = it->getPtr(); + if (const PathDiagnosticCallPiece *call = + dyn_cast<PathDiagnosticCallPiece>(piece)) { + IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter = + call->getCallEnterEvent(); + if (callEnter) + currentPath.push_back(callEnter); + flattenPath(primaryPath, primaryPath, call->path); + IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit = + call->getCallExitEvent(); + if (callExit) + currentPath.push_back(callExit); + continue; + } + if (PathDiagnosticMacroPiece *macro = + dyn_cast<PathDiagnosticMacroPiece>(piece)) { + currentPath.push_back(piece); + PathPieces newPath; + flattenPath(primaryPath, newPath, macro->subPieces); + macro->subPieces = newPath; + continue; + } + + currentPath.push_back(piece); } - - BatchedDiags.clear(); } void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, - SmallVectorImpl<std::string> *FilesMade){ + SmallVectorImpl<std::string> *FilesMade) { + // Create the HTML directory if it is missing. if (!createdDir) { createdDir = true; @@ -138,47 +151,29 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, if (noDir) return; - const SourceManager &SMgr = D.begin()->getLocation().getManager(); - FileID FID; - - // Verify that the entire path is from the same FileID. - for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) { - FullSourceLoc L = I->getLocation().asLocation().getExpansionLoc(); - - if (FID.isInvalid()) { - FID = SMgr.getFileID(L); - } else if (SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? - - // Check the source ranges. - for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(), - RE=I->ranges_end(); RI!=RE; ++RI) { - - SourceLocation L = SMgr.getExpansionLoc(RI->getBegin()); - - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? - - L = SMgr.getExpansionLoc(RI->getEnd()); - - if (!L.isFileID() || SMgr.getFileID(L) != FID) - return; // FIXME: Emit a warning? - } - } + // First flatten out the entire path to make it easier to use. + PathPieces path; + flattenPath(path, path, D.path); - if (FID.isInvalid()) - return; // FIXME: Emit a warning? + // The path as already been prechecked that all parts of the path are + // from the same file and that it is non-empty. + const SourceManager &SMgr = (*path.begin())->getLocation().getManager(); + assert(!path.empty()); + FileID FID = + (*path.begin())->getLocation().asLocation().getExpansionLoc().getFileID(); + assert(!FID.isInvalid()); // Create a new rewriter to generate HTML. - Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions()); + Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOpts()); // Process the path. - unsigned n = D.size(); + unsigned n = path.size(); unsigned max = n; - for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend(); - I!=E; ++I, --n) - HandlePiece(R, FID, *I, n, max); + for (PathPieces::const_reverse_iterator I = path.rbegin(), + E = path.rend(); + I != E; ++I, --n) + HandlePiece(R, FID, **I, n, max); // Add line numbers, header, footer, etc. @@ -221,9 +216,9 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, << html::EscapeText(Entry->getName()) << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>" "<a href=\"#EndPath\">line " - << (*D.rbegin()).getLocation().asLocation().getExpansionLineNumber() + << (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber() << ", column " - << (*D.rbegin()).getLocation().asLocation().getExpansionColumnNumber() + << (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber() << "</a></td></tr>\n" "<tr><td class=\"rowname\">Description:</td><td>" << D.getDescription() << "</td></tr>\n"; @@ -261,10 +256,10 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n"; os << "\n<!-- BUGLINE " - << D.back()->getLocation().asLocation().getExpansionLineNumber() + << path.back()->getLocation().asLocation().getExpansionLineNumber() << " -->\n"; - os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n"; + os << "\n<!-- BUGPATHLENGTH " << path.size() << " -->\n"; // Mark the end of the tags. os << "\n<!-- BUGMETAEND -->\n"; @@ -353,6 +348,8 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, const char *Kind = 0; switch (P.getKind()) { + case PathDiagnosticPiece::Call: + llvm_unreachable("Calls should already be handled"); case PathDiagnosticPiece::Event: Kind = "Event"; break; case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break; // Setting Kind to "Control" is intentional. @@ -445,7 +442,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, assert(L.isFileID()); StringRef BufferInfo = L.getBufferData(); const char* MacroName = L.getDecomposedLoc().second + BufferInfo.data(); - Lexer rawLexer(L, PP.getLangOptions(), BufferInfo.begin(), + Lexer rawLexer(L, PP.getLangOpts(), BufferInfo.begin(), MacroName, BufferInfo.end()); Token TheTok; @@ -518,7 +515,7 @@ unsigned HTMLDiagnostics::ProcessMacroPiece(raw_ostream &os, const PathDiagnosticMacroPiece& P, unsigned num) { - for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end(); + for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end(); I!=E; ++I) { if (const PathDiagnosticMacroPiece *MP = |