summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-08-16 01:06:30 +0000
committerJordan Rose <jordan_rose@apple.com>2013-08-16 01:06:30 +0000
commit367843a04c02cc076f943e22a89429066b2940fd (patch)
tree157381721182d4069c3a1e56c0bd661fa36707f9 /clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
parent9efbedfd352e2cff67c5b9e10c5e22c392008ce5 (diff)
downloadbcm5719-llvm-367843a04c02cc076f943e22a89429066b2940fd.tar.gz
bcm5719-llvm-367843a04c02cc076f943e22a89429066b2940fd.zip
[analyzer] Merge TextPathDiagnostics and ClangDiagPathDiagConsumer.
This once again restores notes to following their associated warnings in -analyzer-output=text mode. (This is still only intended for use as a debugging aid.) One twist is that the warning locations in "regular" analysis output modes (plist, multi-file-plist, html, and plist-html) are reported at a different location on the command line than in the output file, since the command line has no path context. This commit makes -analyzer-output=text behave like a normal output format, which means that the *command line output will be different* in -analyzer-text mode. Again, since -analyzer-text is a debugging aid and lo-fi stand-in for a regular output mode, this change makes sense. Along the way, remove a few pieces of stale code related to the path diagnostic consumers. llvm-svn: 188514
Diffstat (limited to 'clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp74
1 files changed, 55 insertions, 19 deletions
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 64ba5f64844..abc1e9fc529 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -66,23 +66,52 @@ STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
// Special PathDiagnosticConsumers.
//===----------------------------------------------------------------------===//
-static void createPlistHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
- PathDiagnosticConsumers &C,
- const std::string &prefix,
- const Preprocessor &PP) {
+void ento::createPlistHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
+ PathDiagnosticConsumers &C,
+ const std::string &prefix,
+ const Preprocessor &PP) {
createHTMLDiagnosticConsumer(AnalyzerOpts, C,
llvm::sys::path::parent_path(prefix), PP);
createPlistDiagnosticConsumer(AnalyzerOpts, C, prefix, PP);
}
+void ento::createTextPathDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
+ PathDiagnosticConsumers &C,
+ const std::string &Prefix,
+ const clang::Preprocessor &PP) {
+ llvm_unreachable("'text' consumer should be enabled on ClangDiags");
+}
+
namespace {
class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
DiagnosticsEngine &Diag;
+ bool IncludePath;
public:
- ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag) : Diag(Diag) {}
+ ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag)
+ : Diag(Diag), IncludePath(false) {}
virtual ~ClangDiagPathDiagConsumer() {}
virtual StringRef getName() const { return "ClangDiags"; }
- virtual PathGenerationScheme getGenerationScheme() const { return None; }
+
+ virtual bool supportsLogicalOpControlFlow() const { return true; }
+ virtual bool supportsCrossFileDiagnostics() const { return true; }
+
+ virtual PathGenerationScheme getGenerationScheme() const {
+ return IncludePath ? Minimal : None;
+ }
+
+ void enablePaths() {
+ IncludePath = true;
+ }
+
+ void emitDiag(SourceLocation L, unsigned DiagID,
+ ArrayRef<SourceRange> Ranges) {
+ DiagnosticBuilder DiagBuilder = Diag.Report(L, DiagID);
+
+ for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
+ I != E; ++I) {
+ DiagBuilder << *I;
+ }
+ }
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) {
@@ -102,14 +131,20 @@ public:
unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning,
TmpStr);
SourceLocation L = PD->getLocation().asLocation();
- DiagnosticBuilder diagBuilder = Diag.Report(L, ErrorDiag);
+ emitDiag(L, ErrorDiag, PD->path.back()->getRanges());
+
+ if (!IncludePath)
+ continue;
- // Get the ranges from the last point in the path.
- ArrayRef<SourceRange> Ranges = PD->path.back()->getRanges();
+ PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
+ for (PathPieces::const_iterator PI = FlatPath.begin(),
+ PE = FlatPath.end();
+ PI != PE; ++PI) {
+ unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note,
+ (*PI)->getString());
- for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
- E = Ranges.end(); I != E; ++I) {
- diagBuilder << *I;
+ SourceLocation NoteLoc = (*PI)->getLocation().asLocation();
+ emitDiag(NoteLoc, NoteID, (*PI)->getRanges());
}
}
}
@@ -186,20 +221,21 @@ public:
void DigestAnalyzerOptions() {
// Create the PathDiagnosticConsumer.
- PathConsumers.push_back(new ClangDiagPathDiagConsumer(PP.getDiagnostics()));
+ ClangDiagPathDiagConsumer *clangDiags =
+ new ClangDiagPathDiagConsumer(PP.getDiagnostics());
+ PathConsumers.push_back(clangDiags);
+
+ if (Opts->AnalysisDiagOpt == PD_TEXT) {
+ clangDiags->enablePaths();
- if (!OutDir.empty()) {
+ } else if (!OutDir.empty()) {
switch (Opts->AnalysisDiagOpt) {
default:
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
case PD_##NAME: CREATEFN(*Opts.getPtr(), PathConsumers, OutDir, PP);\
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
}
- } else if (Opts->AnalysisDiagOpt == PD_TEXT) {
- // Create the text client even without a specified output file since
- // it just uses diagnostic notes.
- createTextPathDiagnosticConsumer(*Opts.getPtr(), PathConsumers, "", PP);
}
// Create the analyzer component creators.
OpenPOWER on IntegriCloud