[clang] 7bf871c - [analyzer][NFC] Move the text output type to its own file, move code to PathDiagnosticConsumer creator functions

Kirstóf Umann via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 23 13:50:49 PDT 2020


Author: Kirstóf Umann
Date: 2020-03-23T21:50:40+01:00
New Revision: 7bf871c39f739a7382ba89c97f50fd047f36f894

URL: https://github.com/llvm/llvm-project/commit/7bf871c39f739a7382ba89c97f50fd047f36f894
DIFF: https://github.com/llvm/llvm-project/commit/7bf871c39f739a7382ba89c97f50fd047f36f894.diff

LOG: [analyzer][NFC] Move the text output type to its own file, move code to PathDiagnosticConsumer creator functions

TableGen and .def files (which are meant to be used with the preprocessor) come
with obvious downsides. One of those issues is that generated switch-case
branches have to be identical. This pushes corner cases either to an outer code
block, or into the generated code.

Inspect the removed code in AnalysisConsumer::DigestAnalyzerOptions. You can see
how corner cases like a not existing output file, the analysis output type being
set to PD_NONE, or whether to complement the output with additional diagnostics
on stderr lay around the preprocessor generated code. This is a bit problematic,
as to how to deal with such errors is not in the hands of the users of this
interface (those implementing output types, like PlistDiagnostics etc).

This patch changes this by moving these corner cases into the generated code,
more specifically, into the called functions. In addition, I introduced a new
output type for convenience purposes, PD_TEXT_MINIMAL, which always existed
conceptually, but never in the actual Analyses.def file. This refactoring
allowed me to move TextDiagnostics (renamed from ClangDiagPathDiagConsumer) to
its own file, which it really deserved.

Also, those that had the misfortune to gaze upon Analyses.def will probably
enjoy the sight that a clang-format did on it.

Differential Revision: https://reviews.llvm.org/D76509

Added: 
    clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp

Modified: 
    clang/include/clang/StaticAnalyzer/Core/Analyses.def
    clang/lib/StaticAnalyzer/Core/CMakeLists.txt
    clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
    clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
    clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
    clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/StaticAnalyzer/Core/Analyses.def b/clang/include/clang/StaticAnalyzer/Core/Analyses.def
index 377451576148..c4e5f5be6fd7 100644
--- a/clang/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/clang/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -14,41 +14,80 @@
 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
 #endif
 
-ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager)
+ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store",
+               CreateRegionStoreManager)
 
 #ifndef ANALYSIS_CONSTRAINTS
 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
 #endif
 
-ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
-ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver", CreateZ3ConstraintManager)
+ANALYSIS_CONSTRAINTS(RangeConstraints, "range",
+                     "Use constraint tracking of concrete value ranges",
+                     CreateRangeConstraintManager)
+
+ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver",
+                     CreateZ3ConstraintManager)
 
 #ifndef ANALYSIS_DIAGNOSTICS
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
 #endif
 
-ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(HTML_SINGLE_FILE, "html-single-file", "Output analysis results using HTML (not allowing for multi-file bugs)", createHTMLSingleFileDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for multi-file bugs)", createPlistMultiFileDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(SARIF, "sarif", "Output analysis results in a SARIF file", createSarifDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML",
+                     createHTMLDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(
+    HTML_SINGLE_FILE, "html-single-file",
+    "Output analysis results using HTML (not allowing for multi-file bugs)",
+    createHTMLSingleFileDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists",
+                     createPlistDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(
+    PLIST_MULTI_FILE, "plist-multi-file",
+    "Output analysis results using Plists (allowing for multi-file bugs)",
+    createPlistMultiFileDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html",
+                     "Output analysis results using HTML wrapped with Plists",
+                     createPlistHTMLDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(SARIF, "sarif", "Output analysis results in a SARIF file",
+                     createSarifDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results to stderr",
+                     createTextPathDiagnosticConsumer)
+
+ANALYSIS_DIAGNOSTICS(TEXT_MINIMAL, "text-minimal",
+                     "Emits minimal diagnostics to stderr, stating only the "
+                     "warning message and the associated notes. Usually "
+                     "used in addition to other analysis types",
+                     createTextMinimalPathDiagnosticConsumer)
 
 #ifndef ANALYSIS_PURGE
 #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC)
 #endif
 
-ANALYSIS_PURGE(PurgeStmt,  "statement", "Purge symbols, bindings, and constraints before every statement")
-ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block")
-ANALYSIS_PURGE(PurgeNone,  "none", "Do not purge symbols, bindings, or constraints")
+ANALYSIS_PURGE(
+    PurgeStmt, "statement",
+    "Purge symbols, bindings, and constraints before every statement")
+
+ANALYSIS_PURGE(
+    PurgeBlock, "block",
+    "Purge symbols, bindings, and constraints before every basic block")
+
+ANALYSIS_PURGE(PurgeNone, "none",
+               "Do not purge symbols, bindings, or constraints")
 
 #ifndef ANALYSIS_INLINING_MODE
 #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
 #endif
 
-ANALYSIS_INLINING_MODE(All,  "all", "Analyze all functions as top level")
-ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined")
+ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions as top level")
+
+ANALYSIS_INLINING_MODE(
+    NoRedundancy, "noredundancy",
+    "Do not analyze a function which has been previously inlined")
 
 #undef ANALYSIS_STORE
 #undef ANALYSIS_CONSTRAINTS
@@ -56,4 +95,3 @@ ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function
 #undef ANALYSIS_PURGE
 #undef ANALYSIS_INLINING_MODE
 #undef ANALYSIS_IPA
-

diff  --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt
index 081d922ede80..dc2a6279b737 100644
--- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -45,6 +45,7 @@ add_clang_library(clangStaticAnalyzerCore
   SValBuilder.cpp
   SVals.cpp
   SymbolManager.cpp
+  TextDiagnostics.cpp
   WorkList.cpp
 
   LINK_LIBS
@@ -56,5 +57,6 @@ add_clang_library(clangStaticAnalyzerCore
   clangFrontend
   clangLex
   clangRewrite
+  clangToolingCore
   )
 

diff  --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 002b6070ddcd..184fdcfb3d4b 100644
--- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -66,11 +66,9 @@ class HTMLDiagnostics : public PathDiagnosticConsumer {
   const bool SupportsCrossFileDiagnostics;
 
 public:
-  HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts,
-                  const std::string& prefix,
-                  const Preprocessor &pp,
-                  bool supportsMultipleFiles)
-      : Directory(prefix), PP(pp), AnalyzerOpts(AnalyzerOpts),
+  HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string &OutputDir,
+                  const Preprocessor &pp, bool supportsMultipleFiles)
+      : Directory(OutputDir), PP(pp), AnalyzerOpts(AnalyzerOpts),
         SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
 
   ~HTMLDiagnostics() override { FlushDiagnostics(nullptr); }
@@ -136,16 +134,45 @@ class HTMLDiagnostics : public PathDiagnosticConsumer {
 
 void ento::createHTMLDiagnosticConsumer(
     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
-    const std::string &prefix, const Preprocessor &PP,
-    const cross_tu::CrossTranslationUnitContext &) {
-  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP, true));
+    const std::string &OutputDir, const Preprocessor &PP,
+    const cross_tu::CrossTranslationUnitContext &CTU) {
+
+  // FIXME: HTML is currently our default output type, but if the output
+  // directory isn't specified, it acts like if it was in the minimal text
+  // output mode. This doesn't make much sense, we should have the minimal text
+  // as our default. In the case of backward compatibility concerns, this could
+  // be preserved with -analyzer-config-compatibility-mode=true.
+  createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, OutputDir, PP, CTU);
+
+  // TODO: Emit an error here.
+  if (OutputDir.empty())
+    return;
+
+  C.push_back(new HTMLDiagnostics(AnalyzerOpts, OutputDir, PP, true));
 }
 
 void ento::createHTMLSingleFileDiagnosticConsumer(
+    AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
+    const std::string &OutputDir, const Preprocessor &PP,
+    const cross_tu::CrossTranslationUnitContext &CTU) {
+
+  // TODO: Emit an error here.
+  if (OutputDir.empty())
+    return;
+
+  C.push_back(new HTMLDiagnostics(AnalyzerOpts, OutputDir, PP, false));
+  createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, OutputDir, PP, CTU);
+}
+
+void ento::createPlistHTMLDiagnosticConsumer(
     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
     const std::string &prefix, const Preprocessor &PP,
-    const cross_tu::CrossTranslationUnitContext &) {
-  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP, false));
+    const cross_tu::CrossTranslationUnitContext &CTU) {
+  createHTMLDiagnosticConsumer(
+      AnalyzerOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP,
+      CTU);
+  createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
+  createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index babd1401a5a7..9b6369aee7a8 100644
--- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -45,8 +45,8 @@ namespace {
     AnalyzerOptions &AnOpts;
     const bool SupportsCrossFileDiagnostics;
   public:
-    PlistDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string &prefix,
-                     const Preprocessor &PP,
+    PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
+                     const std::string &OutputFile, const Preprocessor &PP,
                      const cross_tu::CrossTranslationUnitContext &CTU,
                      bool supportsMultipleFiles);
 
@@ -582,19 +582,32 @@ PlistDiagnostics::PlistDiagnostics(
 
 void ento::createPlistDiagnosticConsumer(
     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
-    const std::string &s, const Preprocessor &PP,
+    const std::string &OutputFile, const Preprocessor &PP,
     const cross_tu::CrossTranslationUnitContext &CTU) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, CTU,
+
+  // TODO: Emit an error here.
+  if (OutputFile.empty())
+    return;
+
+  C.push_back(new PlistDiagnostics(AnalyzerOpts, OutputFile, PP, CTU,
                                    /*supportsMultipleFiles*/ false));
+  createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, OutputFile, PP, CTU);
 }
 
 void ento::createPlistMultiFileDiagnosticConsumer(
     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
-    const std::string &s, const Preprocessor &PP,
+    const std::string &OutputFile, const Preprocessor &PP,
     const cross_tu::CrossTranslationUnitContext &CTU) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, CTU,
+
+  // TODO: Emit an error here.
+  if (OutputFile.empty())
+    return;
+
+  C.push_back(new PlistDiagnostics(AnalyzerOpts, OutputFile, PP, CTU,
                                    /*supportsMultipleFiles*/ true));
+  createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, OutputFile, PP, CTU);
 }
+
 void PlistDiagnostics::FlushDiagnosticsImpl(
                                     std::vector<const PathDiagnostic *> &Diags,
                                     FilesMade *filesMade) {

diff  --git a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
index eed45aed620f..8c2e85601576 100644
--- a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
@@ -50,8 +50,14 @@ class SarifDiagnostics : public PathDiagnosticConsumer {
 void ento::createSarifDiagnosticConsumer(
     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
     const std::string &Output, const Preprocessor &PP,
-    const cross_tu::CrossTranslationUnitContext &) {
+    const cross_tu::CrossTranslationUnitContext &CTU) {
+
+  // TODO: Emit an error here.
+  if (Output.empty())
+    return;
+
   C.push_back(new SarifDiagnostics(AnalyzerOpts, Output, PP.getLangOpts()));
+  createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, Output, PP, CTU);
 }
 
 static StringRef getFileName(const FileEntry &FE) {

diff  --git a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp
new file mode 100644
index 000000000000..07e5685e604c
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp
@@ -0,0 +1,148 @@
+//===--- TextDiagnostics.cpp - Text Diagnostics for Paths -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TextDiagnostics object.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
+#include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+
+using namespace clang;
+using namespace ento;
+using namespace tooling;
+
+namespace {
+/// Emitsd minimal diagnostics (report message + notes) for the 'none' output
+/// type to the standard error, or to to compliment many others. Emits detailed
+/// diagnostics in textual format for the 'text' output type.
+class TextDiagnostics : public PathDiagnosticConsumer {
+  DiagnosticsEngine &DiagEng;
+  LangOptions LO;
+  const bool IncludePath = false;
+  const bool ShouldEmitAsError = false;
+  const bool ApplyFixIts = false;
+
+public:
+  TextDiagnostics(DiagnosticsEngine &DiagEng, LangOptions LO,
+                  bool ShouldIncludePath, const AnalyzerOptions &AnOpts)
+      : DiagEng(DiagEng), LO(LO), IncludePath(ShouldIncludePath),
+        ShouldEmitAsError(AnOpts.AnalyzerWerror),
+        ApplyFixIts(AnOpts.ShouldApplyFixIts) {}
+  ~TextDiagnostics() override {}
+
+  StringRef getName() const override { return "TextDiagnostics"; }
+
+  bool supportsLogicalOpControlFlow() const override { return true; }
+  bool supportsCrossFileDiagnostics() const override { return true; }
+
+  PathGenerationScheme getGenerationScheme() const override {
+    return IncludePath ? Minimal : None;
+  }
+
+  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
+                            FilesMade *filesMade) override {
+    unsigned WarnID =
+        ShouldEmitAsError
+            ? DiagEng.getCustomDiagID(DiagnosticsEngine::Error, "%0")
+            : DiagEng.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
+    unsigned NoteID = DiagEng.getCustomDiagID(DiagnosticsEngine::Note, "%0");
+    SourceManager &SM = DiagEng.getSourceManager();
+
+    Replacements Repls;
+    auto reportPiece = [&](unsigned ID, FullSourceLoc Loc, StringRef String,
+                           ArrayRef<SourceRange> Ranges,
+                           ArrayRef<FixItHint> Fixits) {
+      if (!ApplyFixIts) {
+        DiagEng.Report(Loc, ID) << String << Ranges << Fixits;
+        return;
+      }
+
+      DiagEng.Report(Loc, ID) << String << Ranges;
+      for (const FixItHint &Hint : Fixits) {
+        Replacement Repl(SM, Hint.RemoveRange, Hint.CodeToInsert);
+
+        if (llvm::Error Err = Repls.add(Repl)) {
+          llvm::errs() << "Error applying replacement " << Repl.toString()
+                       << ": " << Err << "\n";
+        }
+      }
+    };
+
+    for (std::vector<const PathDiagnostic *>::iterator I = Diags.begin(),
+         E = Diags.end();
+         I != E; ++I) {
+      const PathDiagnostic *PD = *I;
+      reportPiece(WarnID, PD->getLocation().asLocation(),
+                  PD->getShortDescription(), PD->path.back()->getRanges(),
+                  PD->path.back()->getFixits());
+
+      // First, add extra notes, even if paths should not be included.
+      for (const auto &Piece : PD->path) {
+        if (!isa<PathDiagnosticNotePiece>(Piece.get()))
+          continue;
+
+        reportPiece(NoteID, Piece->getLocation().asLocation(),
+                    Piece->getString(), Piece->getRanges(), Piece->getFixits());
+      }
+
+      if (!IncludePath)
+        continue;
+
+      // Then, add the path notes if necessary.
+      PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
+      for (const auto &Piece : FlatPath) {
+        if (isa<PathDiagnosticNotePiece>(Piece.get()))
+          continue;
+
+        reportPiece(NoteID, Piece->getLocation().asLocation(),
+                    Piece->getString(), Piece->getRanges(), Piece->getFixits());
+      }
+    }
+
+    if (!ApplyFixIts || Repls.empty())
+      return;
+
+    Rewriter Rewrite(SM, LO);
+    if (!applyAllReplacements(Repls, Rewrite)) {
+      llvm::errs() << "An error occured during applying fix-it.\n";
+    }
+
+    Rewrite.overwriteChangedFiles();
+  }
+};
+} // end anonymous namespace
+
+void ento::createTextPathDiagnosticConsumer(
+    AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
+    const std::string &Prefix, const clang::Preprocessor &PP,
+    const cross_tu::CrossTranslationUnitContext &CTU) {
+  C.emplace_back(new TextDiagnostics(PP.getDiagnostics(), PP.getLangOpts(),
+                                     /*ShouldIncludePath*/ true, AnalyzerOpts));
+}
+
+void ento::createTextMinimalPathDiagnosticConsumer(
+    AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
+    const std::string &Prefix, const clang::Preprocessor &PP,
+    const cross_tu::CrossTranslationUnitContext &CTU) {
+  C.emplace_back(new TextDiagnostics(PP.getDiagnostics(), PP.getLangOpts(),
+                                     /*ShouldIncludePath*/ false,
+                                     AnalyzerOpts));
+}

diff  --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index a908aede68bb..7e1e090afa60 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -64,126 +64,6 @@ STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
 STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
 STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
 
-//===----------------------------------------------------------------------===//
-// Special PathDiagnosticConsumers.
-//===----------------------------------------------------------------------===//
-
-void ento::createPlistHTMLDiagnosticConsumer(
-    AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
-    const std::string &prefix, const Preprocessor &PP,
-    const cross_tu::CrossTranslationUnitContext &CTU) {
-  createHTMLDiagnosticConsumer(
-      AnalyzerOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP,
-      CTU);
-  createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
-}
-
-void ento::createTextPathDiagnosticConsumer(
-    AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
-    const std::string &Prefix, const clang::Preprocessor &PP,
-    const cross_tu::CrossTranslationUnitContext &CTU) {
-  llvm_unreachable("'text' consumer should be enabled on ClangDiags");
-}
-
-namespace {
-class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
-  DiagnosticsEngine &Diag;
-  LangOptions LO;
-
-  bool IncludePath = false;
-  bool ShouldEmitAsError = false;
-  bool ApplyFixIts = false;
-
-public:
-  ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag, LangOptions LO)
-      : Diag(Diag), LO(LO) {}
-  ~ClangDiagPathDiagConsumer() override {}
-  StringRef getName() const override { return "ClangDiags"; }
-
-  bool supportsLogicalOpControlFlow() const override { return true; }
-  bool supportsCrossFileDiagnostics() const override { return true; }
-
-  PathGenerationScheme getGenerationScheme() const override {
-    return IncludePath ? Minimal : None;
-  }
-
-  void enablePaths() { IncludePath = true; }
-  void enableWerror() { ShouldEmitAsError = true; }
-  void enableApplyFixIts() { ApplyFixIts = true; }
-
-  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                            FilesMade *filesMade) override {
-    unsigned WarnID =
-        ShouldEmitAsError
-            ? Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")
-            : Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
-    unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0");
-    SourceManager &SM = Diag.getSourceManager();
-
-    Replacements Repls;
-    auto reportPiece = [&](unsigned ID, FullSourceLoc Loc, StringRef String,
-                           ArrayRef<SourceRange> Ranges,
-                           ArrayRef<FixItHint> Fixits) {
-      if (!ApplyFixIts) {
-        Diag.Report(Loc, ID) << String << Ranges << Fixits;
-        return;
-      }
-
-      Diag.Report(Loc, ID) << String << Ranges;
-      for (const FixItHint &Hint : Fixits) {
-        Replacement Repl(SM, Hint.RemoveRange, Hint.CodeToInsert);
-
-        if (llvm::Error Err = Repls.add(Repl)) {
-          llvm::errs() << "Error applying replacement " << Repl.toString()
-                       << ": " << Err << "\n";
-        }
-      }
-    };
-
-    for (std::vector<const PathDiagnostic *>::iterator I = Diags.begin(),
-         E = Diags.end();
-         I != E; ++I) {
-      const PathDiagnostic *PD = *I;
-      reportPiece(WarnID, PD->getLocation().asLocation(),
-                  PD->getShortDescription(), PD->path.back()->getRanges(),
-                  PD->path.back()->getFixits());
-
-      // First, add extra notes, even if paths should not be included.
-      for (const auto &Piece : PD->path) {
-        if (!isa<PathDiagnosticNotePiece>(Piece.get()))
-          continue;
-
-        reportPiece(NoteID, Piece->getLocation().asLocation(),
-                    Piece->getString(), Piece->getRanges(), Piece->getFixits());
-      }
-
-      if (!IncludePath)
-        continue;
-
-      // Then, add the path notes if necessary.
-      PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
-      for (const auto &Piece : FlatPath) {
-        if (isa<PathDiagnosticNotePiece>(Piece.get()))
-          continue;
-
-        reportPiece(NoteID, Piece->getLocation().asLocation(),
-                    Piece->getString(), Piece->getRanges(), Piece->getFixits());
-      }
-    }
-
-    if (!ApplyFixIts || Repls.empty())
-      return;
-
-    Rewriter Rewrite(SM, LO);
-    if (!applyAllReplacements(Repls, Rewrite)) {
-      llvm::errs() << "An error occured during applying fix-it.\n";
-    }
-
-    Rewrite.overwriteChangedFiles();
-  }
-};
-} // end anonymous namespace
-
 //===----------------------------------------------------------------------===//
 // AnalysisConsumer declaration.
 //===----------------------------------------------------------------------===//
@@ -269,31 +149,16 @@ class AnalysisConsumer : public AnalysisASTConsumer,
   }
 
   void DigestAnalyzerOptions() {
-    if (Opts->AnalysisDiagOpt != PD_NONE) {
-      // Create the PathDiagnosticConsumer.
-      ClangDiagPathDiagConsumer *clangDiags =
-          new ClangDiagPathDiagConsumer(PP.getDiagnostics(), PP.getLangOpts());
-      PathConsumers.push_back(clangDiags);
-
-      if (Opts->AnalyzerWerror)
-        clangDiags->enableWerror();
-
-      if (Opts->ShouldApplyFixIts)
-        clangDiags->enableApplyFixIts();
-
-      if (Opts->AnalysisDiagOpt == PD_TEXT) {
-        clangDiags->enablePaths();
-
-      } else if (!OutDir.empty()) {
-        switch (Opts->AnalysisDiagOpt) {
-        default:
+    switch (Opts->AnalysisDiagOpt) {
+    case PD_NONE:
+      break;
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)                    \
   case PD_##NAME:                                                              \
     CREATEFN(*Opts.get(), PathConsumers, OutDir, PP, CTU);                     \
     break;
 #include "clang/StaticAnalyzer/Core/Analyses.def"
-        }
-      }
+    default:
+      llvm_unreachable("Unkown analyzer output type!");
     }
 
     // Create the analyzer component creators.
@@ -329,20 +194,19 @@ class AnalysisConsumer : public AnalysisASTConsumer,
       else if (Mode == AM_Path) {
         llvm::errs() << " (Path, ";
         switch (IMode) {
-          case ExprEngine::Inline_Minimal:
-            llvm::errs() << " Inline_Minimal";
-            break;
-          case ExprEngine::Inline_Regular:
-            llvm::errs() << " Inline_Regular";
-            break;
+        case ExprEngine::Inline_Minimal:
+          llvm::errs() << " Inline_Minimal";
+          break;
+        case ExprEngine::Inline_Regular:
+          llvm::errs() << " Inline_Regular";
+          break;
         }
         llvm::errs() << ")";
-      }
-      else
+      } else
         assert(Mode == (AM_Syntax | AM_Path) && "Unexpected mode!");
 
-      llvm::errs() << ": " << Loc.getFilename() << ' '
-                           << getFunctionName(D) << '\n';
+      llvm::errs() << ": " << Loc.getFilename() << ' ' << getFunctionName(D)
+                   << '\n';
     }
   }
 
@@ -485,7 +349,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
 
   /// Print \p S to stderr if \c Opts->AnalyzerDisplayProgress is set.
   void reportAnalyzerProgress(StringRef S);
-};
+}; // namespace
 } // end anonymous namespace
 
 

diff  --git a/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt b/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
index 6f1151ab0c11..5e7dd8f18cd7 100644
--- a/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt
@@ -21,6 +21,4 @@ add_clang_library(clangStaticAnalyzerFrontend
   clangLex
   clangStaticAnalyzerCheckers
   clangStaticAnalyzerCore
-  clangRewrite
-  clangToolingCore
   )


        


More information about the cfe-commits mailing list