summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp85
1 files changed, 69 insertions, 16 deletions
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index a7e42291f9..c176ab3f55 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -20,6 +20,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/HTMLRewrite.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -39,8 +40,9 @@ class HTMLDiagnostics : public PathDiagnosticConsumer {
std::string Directory;
bool createdDir, noDir;
const Preprocessor &PP;
+ AnalyzerOptions &AnalyzerOpts;
public:
- HTMLDiagnostics(const std::string& prefix, const Preprocessor &pp);
+ HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string& prefix, const Preprocessor &pp);
virtual ~HTMLDiagnostics() { FlushDiagnostics(nullptr); }
@@ -68,16 +70,17 @@ public:
} // end anonymous namespace
-HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix,
+HTMLDiagnostics::HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts,
+ const std::string& prefix,
const Preprocessor &pp)
- : Directory(prefix), createdDir(false), noDir(false), PP(pp) {
+ : Directory(prefix), createdDir(false), noDir(false), PP(pp), AnalyzerOpts(AnalyzerOpts) {
}
void ento::createHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
PathDiagnosticConsumers &C,
const std::string& prefix,
const Preprocessor &PP) {
- C.push_back(new HTMLDiagnostics(prefix, PP));
+ C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP));
}
//===----------------------------------------------------------------------===//
@@ -95,7 +98,7 @@ void HTMLDiagnostics::FlushDiagnosticsImpl(
void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
FilesMade *filesMade) {
-
+
// Create the HTML directory if it is missing.
if (!createdDir) {
createdDir = true;
@@ -126,11 +129,30 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
// Create a new rewriter to generate HTML.
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOpts());
+ // Get the function/method name
+ SmallString<128> declName("unknown");
+ int offsetDecl = 0;
+ if (const Decl *DeclWithIssue = D.getDeclWithIssue()) {
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(DeclWithIssue)) {
+ declName = ND->getDeclName().getAsString();
+ }
+
+ if (const Stmt *Body = DeclWithIssue->getBody()) {
+ // Retrieve the relative position of the declaration which will be used
+ // for the file name
+ FullSourceLoc L(
+ SMgr.getExpansionLoc((*path.rbegin())->getLocation().asLocation()),
+ SMgr);
+ FullSourceLoc FunL(SMgr.getExpansionLoc(Body->getLocStart()), SMgr);
+ offsetDecl = L.getExpansionLineNumber() - FunL.getExpansionLineNumber();
+ }
+ }
+
// Process the path.
unsigned n = path.size();
unsigned max = n;
- for (PathPieces::const_reverse_iterator I = path.rbegin(),
+ for (PathPieces::const_reverse_iterator I = path.rbegin(),
E = path.rend();
I != E; ++I, --n)
HandlePiece(R, FID, **I, n, max);
@@ -163,6 +185,9 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
DirName += '/';
}
+ int LineNumber = (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber();
+ int ColumnNumber = (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber();
+
// Add the name of the file as an <h1> tag.
{
@@ -176,9 +201,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 "
- << (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
+ << LineNumber
<< ", column "
- << (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
+ << ColumnNumber
<< "</a></td></tr>\n"
"<tr><td class=\"rowname\">Description:</td><td>"
<< D.getVerboseDescription() << "</td></tr>\n";
@@ -216,11 +241,11 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
os << "\n<!-- BUGLINE "
- << path.back()->getLocation().asLocation().getExpansionLineNumber()
+ << LineNumber
<< " -->\n";
os << "\n<!-- BUGCOLUMN "
- << path.back()->getLocation().asLocation().getExpansionColumnNumber()
+ << ColumnNumber
<< " -->\n";
os << "\n<!-- BUGPATHLENGTH " << path.size() << " -->\n";
@@ -247,13 +272,41 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
// Create a path for the target HTML file.
int FD;
SmallString<128> Model, ResultPath;
- llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
- if (std::error_code EC =
+ if (!AnalyzerOpts.shouldWriteStableReportFilename()) {
+ llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
+
+ if (std::error_code EC =
llvm::sys::fs::createUniqueFile(Model.str(), FD, ResultPath)) {
- llvm::errs() << "warning: could not create file in '" << Directory
- << "': " << EC.message() << '\n';
- return;
+ llvm::errs() << "warning: could not create file in '" << Directory
+ << "': " << EC.message() << '\n';
+ return;
+ }
+
+ } else {
+ int i = 1;
+ std::error_code EC;
+ do {
+ // Find a filename which is not already used
+ Model = "";
+ llvm::sys::path::append(Model, Directory,
+ "report-" +
+ llvm::sys::path::filename(Entry->getName()) +
+ "-" +
+ declName.c_str() +
+ "-" + std::to_string(offsetDecl) +
+ "-" + std::to_string(i) + ".html");
+ EC = llvm::sys::fs::openFileForWrite(Model.str(),
+ FD,
+ llvm::sys::fs::F_RW |
+ llvm::sys::fs::F_Excl);
+ if (EC && EC != std::errc::file_exists) {
+ llvm::errs() << "warning: could not create file '" << Model.str()
+ << "': " << EC.message() << '\n';
+ return;
+ }
+ i++;
+ } while (EC);
}
llvm::raw_fd_ostream os(FD, true);
@@ -458,7 +511,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
<< (num + 1)
<< ")\">&#x2192;</a></div></td>";
}
-
+
os << "</tr></table>";
}
}