[analyzer] NFC: Move path diagnostic consumer implementations to libAnalysis.

With this change, we're more or less ready to allow users outside
of the Static Analyzer to take advantage of path diagnostic consumers
for emitting their warnings in different formats.

Differential Revision: https://reviews.llvm.org/D67422
This commit is contained in:
Artem Dergachev 2020-07-30 08:52:22 -07:00
parent b76dc111dd
commit 44b7cf2983
15 changed files with 190 additions and 148 deletions

View File

@ -0,0 +1,50 @@
//===-- PathDiagnosticConsumers.def - Visualizing warnings ------*- 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 set of path diagnostic consumers - objects that
// implement different representations of static analysis results.
//
//===----------------------------------------------------------------------===//
#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 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)
#undef ANALYSIS_DIAGNOSTICS

View File

@ -16,6 +16,8 @@
#include <string>
#include <vector>
#include "clang/Analysis/PathDiagnostic.h"
namespace clang {
class AnalyzerOptions;
@ -27,14 +29,14 @@ class CrossTranslationUnitContext;
namespace ento {
class PathDiagnosticConsumer;
typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
typedef std::vector<PathDiagnosticConsumer *> PathDiagnosticConsumers;
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
void CREATEFN(PathDiagnosticConsumerOptions Diagopts, \
PathDiagnosticConsumers &C, const std::string &Prefix, \
const Preprocessor &PP, \
const cross_tu::CrossTranslationUnitContext &CTU);
#include "clang/StaticAnalyzer/Core/Analyses.def"
#include "clang/Analysis/PathDiagnosticConsumers.def"
} // end 'ento' namespace
} // end 'clang' namespace

View File

@ -28,42 +28,6 @@ ANALYSIS_CONSTRAINTS(RangeConstraints, "range",
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 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
@ -91,7 +55,6 @@ ANALYSIS_INLINING_MODE(
#undef ANALYSIS_STORE
#undef ANALYSIS_CONSTRAINTS
#undef ANALYSIS_DIAGNOSTICS
#undef ANALYSIS_PURGE
#undef ANALYSIS_INLINING_MODE
#undef ANALYSIS_IPA

View File

@ -58,7 +58,7 @@ NumConstraints
/// analysis results.
enum AnalysisDiagClients {
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
#include "clang/StaticAnalyzer/Core/Analyses.def"
#include "clang/Analysis/PathDiagnosticConsumers.def"
PD_NONE,
NUM_ANALYSIS_DIAG_CLIENTS
};

View File

@ -16,10 +16,10 @@
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
namespace clang {

View File

@ -3,6 +3,7 @@ module Clang_Analysis {
umbrella "Analysis"
textual header "Analysis/Analyses/ThreadSafetyOps.def"
textual header "Analysis/PathDiagnosticConsumers.def"
module * { export * }

View File

@ -17,14 +17,19 @@ add_clang_library(clangAnalysis
CodeInjector.cpp
Dominators.cpp
ExprMutationAnalyzer.cpp
HTMLPathDiagnosticConsumer.cpp
IssueHash.cpp
LiveVariables.cpp
ObjCNoReturn.cpp
PathDiagnostic.cpp
PlistPathDiagnosticConsumer.cpp
PlistHTMLPathDiagnosticConsumer.cpp
PostOrderCFGView.cpp
ProgramPoint.cpp
ReachableCode.cpp
RetainSummaryManager.cpp
SarifPathDiagnosticConsumer.cpp
TextPathDiagnosticConsumer.cpp
ThreadSafety.cpp
ThreadSafetyCommon.cpp
ThreadSafetyLogical.cpp

View File

@ -1,4 +1,4 @@
//===- HTMLDiagnostics.cpp - HTML Diagnostics for Paths -------------------===//
//===- HTMLPathDiagnosticConsumer.cpp - HTML Diagnostics for Paths --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the HTMLDiagnostics object.
// This file defines the HTMLPathDiagnosticConsumer object.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/IssueHash.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Stmt.h"
@ -24,7 +25,6 @@
#include "clang/Lex/Token.h"
#include "clang/Rewrite/Core/HTMLRewrite.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@ -56,7 +56,7 @@ using namespace ento;
namespace {
class HTMLDiagnostics : public PathDiagnosticConsumer {
class HTMLPathDiagnosticConsumer : public PathDiagnosticConsumer {
PathDiagnosticConsumerOptions DiagOpts;
std::string Directory;
bool createdDir = false;
@ -65,20 +65,18 @@ class HTMLDiagnostics : public PathDiagnosticConsumer {
const bool SupportsCrossFileDiagnostics;
public:
HTMLDiagnostics(PathDiagnosticConsumerOptions DiagOpts,
const std::string &OutputDir, const Preprocessor &pp,
bool supportsMultipleFiles)
: DiagOpts(std::move(DiagOpts)), Directory(OutputDir), PP(pp),
SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
HTMLPathDiagnosticConsumer(PathDiagnosticConsumerOptions DiagOpts,
const std::string &OutputDir,
const Preprocessor &PP, bool SupportsMultipleFiles)
: DiagOpts(std::move(DiagOpts)), Directory(OutputDir), PP(PP),
SupportsCrossFileDiagnostics(SupportsMultipleFiles) {}
~HTMLDiagnostics() override { FlushDiagnostics(nullptr); }
~HTMLPathDiagnosticConsumer() override { FlushDiagnostics(nullptr); }
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) override;
StringRef getName() const override {
return "HTMLDiagnostics";
}
StringRef getName() const override { return "HTMLPathDiagnosticConsumer"; }
bool supportsCrossFileDiagnostics() const override {
return SupportsCrossFileDiagnostics;
@ -148,7 +146,8 @@ void ento::createHTMLDiagnosticConsumer(
if (OutputDir.empty())
return;
C.push_back(new HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP, true));
C.push_back(
new HTMLPathDiagnosticConsumer(std::move(DiagOpts), OutputDir, PP, true));
}
void ento::createHTMLSingleFileDiagnosticConsumer(
@ -161,34 +160,22 @@ void ento::createHTMLSingleFileDiagnosticConsumer(
if (OutputDir.empty())
return;
C.push_back(new HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP, false));
}
void ento::createPlistHTMLDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &prefix, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
createHTMLDiagnosticConsumer(
DiagOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP,
CTU);
createPlistMultiFileDiagnosticConsumer(DiagOpts, C, prefix, PP, CTU);
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, prefix, PP,
CTU);
C.push_back(new HTMLPathDiagnosticConsumer(std::move(DiagOpts), OutputDir, PP,
false));
}
//===----------------------------------------------------------------------===//
// Report processing.
//===----------------------------------------------------------------------===//
void HTMLDiagnostics::FlushDiagnosticsImpl(
std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) {
void HTMLPathDiagnosticConsumer::FlushDiagnosticsImpl(
std::vector<const PathDiagnostic *> &Diags, FilesMade *filesMade) {
for (const auto Diag : Diags)
ReportDiag(*Diag, filesMade);
}
void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
FilesMade *filesMade) {
void HTMLPathDiagnosticConsumer::ReportDiag(const PathDiagnostic &D,
FilesMade *filesMade) {
// Create the HTML directory if it is missing.
if (!createdDir) {
createdDir = true;
@ -296,8 +283,11 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
os << report;
}
std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R,
const SourceManager& SMgr, const PathPieces& path, const char *declName) {
std::string HTMLPathDiagnosticConsumer::GenerateHTML(const PathDiagnostic &D,
Rewriter &R,
const SourceManager &SMgr,
const PathPieces &path,
const char *declName) {
// Rewrite source files as HTML for every new file the path crosses
std::vector<FileID> FileIDs;
for (auto I : path) {
@ -369,9 +359,8 @@ std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R,
return os.str();
}
void HTMLDiagnostics::dumpCoverageData(
const PathDiagnostic &D,
const PathPieces &path,
void HTMLPathDiagnosticConsumer::dumpCoverageData(
const PathDiagnostic &D, const PathPieces &path,
llvm::raw_string_ostream &os) {
const FilesToLineNumsMap &ExecutedLines = D.getExecutedLines();
@ -395,8 +384,8 @@ void HTMLDiagnostics::dumpCoverageData(
os << "};";
}
std::string HTMLDiagnostics::showRelevantLinesJavascript(
const PathDiagnostic &D, const PathPieces &path) {
std::string HTMLPathDiagnosticConsumer::showRelevantLinesJavascript(
const PathDiagnostic &D, const PathPieces &path) {
std::string s;
llvm::raw_string_ostream os(s);
os << "<script type='text/javascript'>\n";
@ -460,9 +449,10 @@ document.addEventListener("DOMContentLoaded", function() {
return os.str();
}
void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
const SourceManager& SMgr, const PathPieces& path, FileID FID,
const FileEntry *Entry, const char *declName) {
void HTMLPathDiagnosticConsumer::FinalizeHTML(
const PathDiagnostic &D, Rewriter &R, const SourceManager &SMgr,
const PathPieces &path, FileID FID, const FileEntry *Entry,
const char *declName) {
// This is a cludge; basically we want to append either the full
// working directory if we have no directory information. This is
// a work in progress.
@ -607,7 +597,7 @@ void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
}
StringRef HTMLDiagnostics::showHelpJavascript() {
StringRef HTMLPathDiagnosticConsumer::showHelpJavascript() {
return R"<<<(
<script type='text/javascript'>
@ -690,8 +680,9 @@ static void HandlePopUpPieceEndTag(Rewriter &R,
}
}
void HTMLDiagnostics::RewriteFile(Rewriter &R,
const PathPieces& path, FileID FID) {
void HTMLPathDiagnosticConsumer::RewriteFile(Rewriter &R,
const PathPieces &path,
FileID FID) {
// Process the path.
// Maintain the counts of extra note pieces separately.
unsigned TotalPieces = path.size();
@ -769,10 +760,9 @@ void HTMLDiagnostics::RewriteFile(Rewriter &R,
html::HighlightMacros(R, FID, PP);
}
void HTMLDiagnostics::HandlePiece(Rewriter &R, FileID BugFileID,
const PathDiagnosticPiece &P,
const std::vector<SourceRange> &PopUpRanges,
unsigned num, unsigned max) {
void HTMLPathDiagnosticConsumer::HandlePiece(
Rewriter &R, FileID BugFileID, const PathDiagnosticPiece &P,
const std::vector<SourceRange> &PopUpRanges, unsigned num, unsigned max) {
// For now, just draw a box above the line in question, and emit the
// warning.
FullSourceLoc Pos = P.getLocation().asLocation();
@ -1004,9 +994,8 @@ static void EmitAlphaCounter(raw_ostream &os, unsigned n) {
os << char('a' + x);
}
unsigned HTMLDiagnostics::ProcessMacroPiece(raw_ostream &os,
const PathDiagnosticMacroPiece& P,
unsigned num) {
unsigned HTMLPathDiagnosticConsumer::ProcessMacroPiece(
raw_ostream &os, const PathDiagnosticMacroPiece &P, unsigned num) {
for (const auto &subPiece : P.subPieces) {
if (const auto *MP = dyn_cast<PathDiagnosticMacroPiece>(subPiece.get())) {
num = ProcessMacroPiece(os, *MP, num);
@ -1028,10 +1017,10 @@ unsigned HTMLDiagnostics::ProcessMacroPiece(raw_ostream &os,
return num;
}
void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
SourceRange Range,
const char *HighlightStart,
const char *HighlightEnd) {
void HTMLPathDiagnosticConsumer::HighlightRange(Rewriter &R, FileID BugFileID,
SourceRange Range,
const char *HighlightStart,
const char *HighlightEnd) {
SourceManager &SM = R.getSourceMgr();
const LangOptions &LangOpts = R.getLangOpts();
@ -1066,7 +1055,7 @@ void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
html::HighlightRange(R, InstantiationStart, E, HighlightStart, HighlightEnd);
}
StringRef HTMLDiagnostics::generateKeyboardNavigationJavascript() {
StringRef HTMLPathDiagnosticConsumer::generateKeyboardNavigationJavascript() {
return R"<<<(
<script type='text/javascript'>
var digitMatcher = new RegExp("[0-9]+");

View File

@ -0,0 +1,31 @@
//===--- PlistHTMLDiagnostics.cpp - The Plist-HTML Diagnostic Consumer. ---===//
//
// 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 diagnostic consumer produces both the HTML output and the Plist output.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.h"
#include "clang/Basic/SourceManager.h"
#include "clang/CrossTU/CrossTranslationUnit.h"
#include "clang/Lex/Preprocessor.h"
using namespace clang;
using namespace ento;
void ento::createPlistHTMLDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &Prefix, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
createHTMLDiagnosticConsumer(
DiagOpts, C, std::string(llvm::sys::path::parent_path(Prefix)), PP, CTU);
createPlistMultiFileDiagnosticConsumer(DiagOpts, C, Prefix, PP, CTU);
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, Prefix, PP,
CTU);
}

View File

@ -1,4 +1,4 @@
//===--- PlistDiagnostics.cpp - Plist Diagnostics for Paths -----*- C++ -*-===//
//===--- PlistPathDiagnosticConsumer.cpp - Plist Diagnostics ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the PlistDiagnostics object.
// This file defines the PlistPathDiagnosticConsumer object.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/IssueHash.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/PlistSupport.h"
#include "clang/Basic/SourceManager.h"
@ -21,7 +22,6 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/TokenConcatenation.h"
#include "clang/Rewrite/Core/HTMLRewrite.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@ -38,7 +38,7 @@ using namespace markup;
//===----------------------------------------------------------------------===//
namespace {
class PlistDiagnostics : public PathDiagnosticConsumer {
class PlistPathDiagnosticConsumer : public PathDiagnosticConsumer {
PathDiagnosticConsumerOptions DiagOpts;
const std::string OutputFile;
const Preprocessor &PP;
@ -49,18 +49,18 @@ namespace {
const PathPieces &Path);
public:
PlistDiagnostics(PathDiagnosticConsumerOptions DiagOpts,
PlistPathDiagnosticConsumer(PathDiagnosticConsumerOptions DiagOpts,
const std::string &OutputFile, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU,
bool supportsMultipleFiles);
~PlistDiagnostics() override {}
~PlistPathDiagnosticConsumer() override {}
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) override;
StringRef getName() const override {
return "PlistDiagnostics";
return "PlistPathDiagnosticConsumer";
}
PathGenerationScheme getGenerationScheme() const override {
@ -516,10 +516,10 @@ static void printCoverage(const PathDiagnostic *D,
}
//===----------------------------------------------------------------------===//
// Methods of PlistDiagnostics.
// Methods of PlistPathDiagnosticConsumer.
//===----------------------------------------------------------------------===//
PlistDiagnostics::PlistDiagnostics(
PlistPathDiagnosticConsumer::PlistPathDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, const std::string &output,
const Preprocessor &PP, const cross_tu::CrossTranslationUnitContext &CTU,
bool supportsMultipleFiles)
@ -538,8 +538,8 @@ void ento::createPlistDiagnosticConsumer(
if (OutputFile.empty())
return;
C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU,
/*supportsMultipleFiles=*/false));
C.push_back(new PlistPathDiagnosticConsumer(DiagOpts, OutputFile, PP, CTU,
/*supportsMultipleFiles=*/false));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile,
PP, CTU);
}
@ -553,14 +553,15 @@ void ento::createPlistMultiFileDiagnosticConsumer(
if (OutputFile.empty())
return;
C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU,
/*supportsMultipleFiles=*/true));
C.push_back(new PlistPathDiagnosticConsumer(DiagOpts, OutputFile, PP, CTU,
/*supportsMultipleFiles=*/true));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile,
PP, CTU);
}
void PlistDiagnostics::printBugPath(llvm::raw_ostream &o, const FIDMap &FM,
const PathPieces &Path) {
void PlistPathDiagnosticConsumer::printBugPath(llvm::raw_ostream &o,
const FIDMap &FM,
const PathPieces &Path) {
PlistPrinter Printer(FM, PP, CTU);
assert(std::is_partitioned(Path.begin(), Path.end(),
[](const PathDiagnosticPieceRef &E) {
@ -603,9 +604,8 @@ void PlistDiagnostics::printBugPath(llvm::raw_ostream &o, const FIDMap &FM,
o << " </array>\n";
}
void PlistDiagnostics::FlushDiagnosticsImpl(
std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) {
void PlistPathDiagnosticConsumer::FlushDiagnosticsImpl(
std::vector<const PathDiagnostic *> &Diags, FilesMade *filesMade) {
// Build up a set of FIDs that we use by scanning the locations and
// ranges of the diagnostics.
FIDMap FM;

View File

@ -1,4 +1,4 @@
//===--- SarifDiagnostics.cpp - Sarif Diagnostics for Paths -----*- C++ -*-===//
//===--- SarifPathDiagnosticConsumer.cpp - Sarif Diagnostics ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,15 +6,15 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the SarifDiagnostics object.
// This file defines the SarifPathDiagnosticConsumer object.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/Version.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ConvertUTF.h"
@ -26,19 +26,19 @@ using namespace clang;
using namespace ento;
namespace {
class SarifDiagnostics : public PathDiagnosticConsumer {
class SarifPathDiagnosticConsumer : public PathDiagnosticConsumer {
std::string OutputFile;
const LangOptions &LO;
public:
SarifDiagnostics(const std::string &Output, const LangOptions &LO)
SarifPathDiagnosticConsumer(const std::string &Output, const LangOptions &LO)
: OutputFile(Output), LO(LO) {}
~SarifDiagnostics() override = default;
~SarifPathDiagnosticConsumer() override = default;
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
FilesMade *FM) override;
StringRef getName() const override { return "SarifDiagnostics"; }
StringRef getName() const override { return "SarifPathDiagnosticConsumer"; }
PathGenerationScheme getGenerationScheme() const override { return Minimal; }
bool supportsLogicalOpControlFlow() const override { return true; }
bool supportsCrossFileDiagnostics() const override { return true; }
@ -54,7 +54,7 @@ void ento::createSarifDiagnosticConsumer(
if (Output.empty())
return;
C.push_back(new SarifDiagnostics(Output, PP.getLangOpts()));
C.push_back(new SarifPathDiagnosticConsumer(Output, PP.getLangOpts()));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, Output, PP,
CTU);
}
@ -300,6 +300,9 @@ static json::Object createResult(const LangOptions &LO,
}
static StringRef getRuleDescription(StringRef CheckName) {
// FIXME: This is a layering violation; it only works for the particular
// use-case of clang static analyzer. This info should be provided
// as part of PathDiagnostic itself.
return llvm::StringSwitch<StringRef>(CheckName)
#define GET_CHECKERS
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
@ -311,6 +314,9 @@ static StringRef getRuleDescription(StringRef CheckName) {
}
static StringRef getRuleHelpURIStr(StringRef CheckName) {
// FIXME: This is a layering violation; it only works for the particular
// use-case of clang static analyzer. This info should be provided
// as part of PathDiagnostic itself.
return llvm::StringSwitch<StringRef>(CheckName)
#define GET_CHECKERS
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
@ -378,7 +384,7 @@ static json::Object createRun(const LangOptions &LO,
{"columnKind", "unicodeCodePoints"}};
}
void SarifDiagnostics::FlushDiagnosticsImpl(
void SarifPathDiagnosticConsumer::FlushDiagnosticsImpl(
std::vector<const PathDiagnostic *> &Diags, FilesMade *) {
// We currently overwrite the file if it already exists. However, it may be
// useful to add a feature someday that allows the user to append a run to an

View File

@ -1,4 +1,4 @@
//===--- TextDiagnostics.cpp - Text Diagnostics for Paths -------*- C++ -*-===//
//===--- TextPathDiagnosticConsumer.cpp - Text Diagnostics ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,19 +6,18 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the TextDiagnostics object.
// This file defines the TextPathDiagnosticConsumer object.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.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"
@ -33,21 +32,21 @@ 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 {
class TextPathDiagnosticConsumer : public PathDiagnosticConsumer {
PathDiagnosticConsumerOptions DiagOpts;
DiagnosticsEngine &DiagEng;
const LangOptions &LO;
bool ShouldDisplayPathNotes;
public:
TextDiagnostics(PathDiagnosticConsumerOptions DiagOpts,
DiagnosticsEngine &DiagEng, const LangOptions &LO,
bool ShouldDisplayPathNotes)
TextPathDiagnosticConsumer(PathDiagnosticConsumerOptions DiagOpts,
DiagnosticsEngine &DiagEng, const LangOptions &LO,
bool ShouldDisplayPathNotes)
: DiagOpts(std::move(DiagOpts)), DiagEng(DiagEng), LO(LO),
ShouldDisplayPathNotes(ShouldDisplayPathNotes) {}
~TextDiagnostics() override {}
~TextPathDiagnosticConsumer() override {}
StringRef getName() const override { return "TextDiagnostics"; }
StringRef getName() const override { return "TextPathDiagnosticConsumer"; }
bool supportsLogicalOpControlFlow() const override { return true; }
bool supportsCrossFileDiagnostics() const override { return true; }
@ -140,16 +139,16 @@ void ento::createTextPathDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &Prefix, const clang::Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
C.emplace_back(new TextDiagnostics(std::move(DiagOpts), PP.getDiagnostics(),
PP.getLangOpts(),
/*ShouldDisplayPathNotes=*/true));
C.emplace_back(new TextPathDiagnosticConsumer(
std::move(DiagOpts), PP.getDiagnostics(), PP.getLangOpts(),
/*ShouldDisplayPathNotes=*/true));
}
void ento::createTextMinimalPathDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &Prefix, const clang::Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
C.emplace_back(new TextDiagnostics(std::move(DiagOpts), PP.getDiagnostics(),
PP.getLangOpts(),
/*ShouldDisplayPathNotes=*/false));
C.emplace_back(new TextPathDiagnosticConsumer(
std::move(DiagOpts), PP.getDiagnostics(), PP.getLangOpts(),
/*ShouldDisplayPathNotes=*/false));
}

View File

@ -301,7 +301,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
.Case(CMDFLAG, PD_##NAME)
#include "clang/StaticAnalyzer/Core/Analyses.def"
#include "clang/Analysis/PathDiagnosticConsumers.def"
.Default(NUM_ANALYSIS_DIAG_CLIENTS);
if (Value == NUM_ANALYSIS_DIAG_CLIENTS) {
Diags.Report(diag::err_drv_invalid_value)

View File

@ -30,16 +30,13 @@ add_clang_library(clangStaticAnalyzerCore
ExprEngineCallAndReturn.cpp
ExprEngineObjC.cpp
FunctionSummary.cpp
HTMLDiagnostics.cpp
LoopUnrolling.cpp
LoopWidening.cpp
MemRegion.cpp
PlistDiagnostics.cpp
ProgramState.cpp
RangeConstraintManager.cpp
RangedConstraintManager.cpp
RegionStore.cpp
SarifDiagnostics.cpp
SimpleConstraintManager.cpp
SimpleSValBuilder.cpp
SMTConstraintManager.cpp
@ -47,7 +44,6 @@ add_clang_library(clangStaticAnalyzerCore
SValBuilder.cpp
SVals.cpp
SymbolManager.cpp
TextDiagnostics.cpp
WorkList.cpp
LINK_LIBS

View File

@ -21,6 +21,7 @@
#include "clang/Analysis/CallGraph.h"
#include "clang/Analysis/CodeInjector.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathDiagnosticConsumers.h"
#include "clang/Basic/SourceManager.h"
#include "clang/CrossTU/CrossTranslationUnit.h"
#include "clang/Frontend/CompilerInstance.h"
@ -30,7 +31,6 @@
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/ADT/PostOrderIterator.h"
@ -152,7 +152,7 @@ public:
case PD_##NAME: \
CREATEFN(Opts->getDiagOpts(), PathConsumers, OutDir, PP, CTU); \
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
#include "clang/Analysis/PathDiagnosticConsumers.def"
default:
llvm_unreachable("Unknown analyzer output type!");
}