aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-08-24 19:35:19 +0000
committerTed Kremenek <kremenek@apple.com>2012-08-24 19:35:19 +0000
commitb75e2602e246b44bb285be8cc31166302d77998f (patch)
tree3874104d9b0d49062247c4b8c0f2b5d66580ec7a
parent81e6cfddcbb32eb9bbbee5c3f5156fc19ca7e774 (diff)
Rework how PathDiagnosticConsumers pass knowledge of what files they
generated for a given diagnostic to another. Because PathDiagnostics are specific to a give PathDiagnosticConsumer, store in a FoldingSet a unique hash for a PathDiagnostic (that will be the same for the same bug for different PathDiagnosticConsumers) that stores a list of files generated. This can then be read by the other PathDiagnosticConsumers. This fixes breakage in the PLIST-HTML output. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162580 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h26
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp40
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp21
4 files changed, 76 insertions, 14 deletions
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 973cfb109c..ad8a0694b4 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -52,7 +52,31 @@ class PathDiagnostic;
class PathDiagnosticConsumer {
public:
- typedef std::vector<std::pair<StringRef, std::string> > FilesMade;
+ class PDFileEntry : public llvm::FoldingSetNode {
+ public:
+ PDFileEntry(llvm::FoldingSetNodeID &NodeID) : NodeID(NodeID) {}
+
+ typedef std::vector<std::pair<StringRef, StringRef> > ConsumerFiles;
+
+ /// \brief A vector of <consumer,file> pairs.
+ ConsumerFiles files;
+
+ /// \brief A precomputed hash tag used for uniquing PDFileEntry objects.
+ const llvm::FoldingSetNodeID NodeID;
+
+ /// \brief Used for profiling in the FoldingSet.
+ void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; }
+ };
+
+ struct FilesMade : public llvm::FoldingSet<PDFileEntry> {
+ llvm::BumpPtrAllocator Alloc;
+
+ void addDiagnostic(const PathDiagnostic &PD,
+ StringRef ConsumerName,
+ StringRef fileName);
+
+ PDFileEntry::ConsumerFiles *getFiles(const PathDiagnostic &PD);
+ };
private:
virtual void anchor();
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 982bcbfcdf..46adfbd795 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -267,8 +267,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
}
if (filesMade) {
- filesMade->push_back(std::make_pair(StringRef(getName()),
- llvm::sys::path::filename(H.str())));
+ filesMade->addDiagnostic(D, getName(), llvm::sys::path::filename(H.str()));
}
// Emit the HTML to disk.
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index c849778e7f..97ef906cac 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -271,6 +271,46 @@ void PathDiagnosticConsumer::FlushDiagnostics(
}
}
+static void ProfileDiagnostic(const PathDiagnostic &PD,
+ llvm::FoldingSetNodeID &NodeID) {
+ NodeID.AddString(PD.getBugType());
+ NodeID.AddString(PD.getDescription());
+ NodeID.Add(PD.getLocation());
+}
+
+void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD,
+ StringRef ConsumerName,
+ StringRef FileName) {
+ llvm::FoldingSetNodeID NodeID;
+ ProfileDiagnostic(PD, NodeID);
+ void *InsertPos;
+ PDFileEntry *Entry = FindNodeOrInsertPos(NodeID, InsertPos);
+ if (!Entry) {
+ Entry = Alloc.Allocate<PDFileEntry>();
+ Entry = new (Entry) PDFileEntry(NodeID);
+ InsertNode(Entry, InsertPos);
+ }
+
+ // Allocate persistent storage for the file name.
+ char *FileName_cstr = (char*) Alloc.Allocate(FileName.size(), 1);
+ memcpy(FileName_cstr, FileName.data(), FileName.size());
+
+ Entry->files.push_back(std::make_pair(ConsumerName,
+ StringRef(FileName_cstr,
+ FileName.size())));
+}
+
+PathDiagnosticConsumer::PDFileEntry::ConsumerFiles *
+PathDiagnosticConsumer::FilesMade::getFiles(const PathDiagnostic &PD) {
+ llvm::FoldingSetNodeID NodeID;
+ ProfileDiagnostic(PD, NodeID);
+ void *InsertPos;
+ PDFileEntry *Entry = FindNodeOrInsertPos(NodeID, InsertPos);
+ if (!Entry)
+ return 0;
+ return &Entry->files;
+}
+
//===----------------------------------------------------------------------===//
// PathDiagnosticLocation methods.
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index d5fdd9d2bb..79b2a1ce7f 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -499,17 +499,21 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
// Output the diagnostic to the sub-diagnostic client, if any.
if (!filesMade->empty()) {
StringRef lastName;
- for (FilesMade::iterator I = filesMade->begin(), E = filesMade->end();
- I != E; ++I) {
- StringRef newName = I->first;
+ PDFileEntry::ConsumerFiles *files = filesMade->getFiles(*D);
+ if (!files)
+ continue;
+ for (PDFileEntry::ConsumerFiles::const_iterator CI = files->begin(),
+ CE = files->end(); CI != CE; ++CI) {
+ StringRef newName = CI->first;
if (newName != lastName) {
- if (!lastName.empty())
+ if (!lastName.empty()) {
o << " </array>\n";
+ }
lastName = newName;
o << " <key>" << lastName << "_files</key>\n";
o << " <array>\n";
}
- o << " <string>" << I->second << "</string>\n";
+ o << " <string>" << CI->second << "</string>\n";
}
o << " </array>\n";
}
@@ -521,10 +525,5 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
o << " </array>\n";
// Finish.
- o << "</dict>\n</plist>";
-
- if (filesMade) {
- StringRef Name(getName());
- filesMade->push_back(std::make_pair(Name, OutputFile));
- }
+ o << "</dict>\n</plist>";
}