aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-02-24 00:38:56 +0000
committerTed Kremenek <kremenek@apple.com>2012-02-24 00:38:56 +0000
commit4970ef8e3527ac356c3e9fde0710561fcb63e424 (patch)
tree2b624077752e8ea3755cd4a470e39597767d0f27 /lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
parent729d5c4959fbe01e22554e56a35639173388911a (diff)
Rework PathDiagnostic creation so that call stacks are captured by a nested PathDiagnosticCallPiece.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151317 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index e39d32db96..8004ef45a6 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -95,8 +95,31 @@ void HTMLDiagnostics::FlushDiagnosticsImpl(
}
}
+static void flattenPath(PathPieces &path, 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)
+ path.push_back(callEnter);
+ flattenPath(path, call->path);
+ IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
+ call->getCallExitEvent();
+ if (callExit)
+ path.push_back(callExit);
+ continue;
+ }
+
+ path.push_back(piece);
+ }
+}
+
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;
@@ -119,11 +142,15 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
if (noDir)
return;
- const SourceManager &SMgr = (*D.path.begin())->getLocation().getManager();
+ // First flatten out the entire path to make it easier to use.
+ PathPieces path;
+ flattenPath(path, D.path);
+
+ const SourceManager &SMgr = (*path.begin())->getLocation().getManager();
FileID FID;
// Verify that the entire path is from the same FileID.
- for (PathPieces::const_iterator I = D.path.begin(), E = D.path.end();
+ for (PathPieces::const_iterator I = path.begin(), E = path.end();
I != E; ++I) {
FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
@@ -152,10 +179,11 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
// Process the path.
- unsigned n = D.path.size();
+ unsigned n = path.size();
unsigned max = n;
- for (PathPieces::const_reverse_iterator I = D.path.rbegin(), E=D.path.rend();
+ for (PathPieces::const_reverse_iterator I = path.rbegin(),
+ E = path.rend();
I != E; ++I, --n)
HandlePiece(R, FID, **I, n, max);
@@ -200,9 +228,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.path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
+ << (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
<< ", column "
- << (*D.path.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";
@@ -240,10 +268,10 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
os << "\n<!-- BUGLINE "
- << D.path.back()->getLocation().asLocation().getExpansionLineNumber()
+ << path.back()->getLocation().asLocation().getExpansionLineNumber()
<< " -->\n";
- os << "\n<!-- BUGPATHLENGTH " << D.path.size() << " -->\n";
+ os << "\n<!-- BUGPATHLENGTH " << path.size() << " -->\n";
// Mark the end of the tags.
os << "\n<!-- BUGMETAEND -->\n";
@@ -332,8 +360,8 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
const char *Kind = 0;
switch (P.getKind()) {
- case PathDiagnosticPiece::CallEnter:
- case PathDiagnosticPiece::CallExit:
+ 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.