[analyzer] NFC: Separate PathDiagnosticConsumer options from AnalyzerOptions.

The AnalyzerOptions object contains too much information that's
entirely specific to the Analyzer. It is also being referenced by
path diagnostic consumers to tweak their behavior. In order for path
diagnostic consumers to function separately from the analyzer,
make a smaller options object that only contains relevant options.

Differential Revision: https://reviews.llvm.org/D67420
This commit is contained in:
Artem Dergachev 2020-07-13 21:13:31 -07:00
parent 0ccf9263cc
commit fd4b3f123d
8 changed files with 162 additions and 116 deletions

View File

@ -58,6 +58,47 @@ namespace ento {
class PathDiagnostic;
/// These options tweak the behavior of path diangostic consumers.
/// Most of these options are currently supported by very few consumers.
struct PathDiagnosticConsumerOptions {
/// Run-line of the tool that produced the diagnostic.
/// It can be included with the diagnostic for debugging purposes.
std::string ToolInvocation;
/// Whether to include additional information about macro expansions
/// with the diagnostics, because otherwise they can be hard to obtain
/// without re-compiling the program under analysis.
bool ShouldDisplayMacroExpansions;
/// Whether to include LLVM statistics of the process in the diagnostic.
/// Useful for profiling the tool on large real-world codebases.
bool ShouldSerializeStats;
/// If the consumer intends to produce multiple output files, should it
/// use randomly generated file names for these files (with the tiny risk of
/// having random collisions) or deterministic human-readable file names
/// (with a larger risk of deterministic collisions or invalid characters
/// in the file name). We should not really give this choice to the users
/// because deterministic mode is always superior when done right, but
/// for some consumers this mode is experimental and needs to be
/// off by default.
bool ShouldWriteStableReportFilename;
/// Whether the consumer should treat consumed diagnostics as hard errors.
/// Useful for breaking your build when issues are found.
bool ShouldDisplayWarningsAsErrors;
/// Whether the consumer should attempt to rewrite the source file
/// with fix-it hints attached to the diagnostics it consumes.
bool ShouldApplyFixIts;
/// Whether the consumer should present the name of the entity that emitted
/// the diagnostic (eg., a checker) so that the user knew how to disable it.
bool ShouldDisplayDiagnosticName;
PathDiagnosticConsumerOptions() = delete;
};
class PathDiagnosticConsumer {
public:
class PDFileEntry : public llvm::FoldingSetNode {

View File

@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
#define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
@ -255,7 +256,7 @@ public:
unsigned NoRetryExhausted : 1;
/// Emit analyzer warnings as errors.
unsigned AnalyzerWerror : 1;
bool AnalyzerWerror : 1;
/// The inlining stack depth limit.
// Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
@ -390,6 +391,16 @@ public:
///
/// \sa CXXMemberInliningMode
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
ento::PathDiagnosticConsumerOptions getDiagOpts() const {
return {FullCompilerInvocation,
ShouldDisplayMacroExpansions,
ShouldSerializeStats,
ShouldWriteStableReportFilename,
AnalyzerWerror,
ShouldApplyFixIts,
ShouldDisplayCheckerNameForText};
}
};
using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;

View File

@ -30,8 +30,9 @@ class PathDiagnosticConsumer;
typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
void CREATEFN(AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C, \
const std::string &Prefix, const Preprocessor &PP, \
void CREATEFN(PathDiagnosticConsumerOptions Diagopts, \
PathDiagnosticConsumers &C, const std::string &Prefix, \
const Preprocessor &PP, \
const cross_tu::CrossTranslationUnitContext &CTU);
#include "clang/StaticAnalyzer/Core/Analyses.def"

View File

@ -23,7 +23,6 @@
#include "clang/Lex/Token.h"
#include "clang/Rewrite/Core/HTMLRewrite.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/IssueHash.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/ArrayRef.h"
@ -58,17 +57,18 @@ using namespace ento;
namespace {
class HTMLDiagnostics : public PathDiagnosticConsumer {
PathDiagnosticConsumerOptions DiagOpts;
std::string Directory;
bool createdDir = false;
bool noDir = false;
const Preprocessor &PP;
AnalyzerOptions &AnalyzerOpts;
const bool SupportsCrossFileDiagnostics;
public:
HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string &OutputDir,
const Preprocessor &pp, bool supportsMultipleFiles)
: Directory(OutputDir), PP(pp), AnalyzerOpts(AnalyzerOpts),
HTMLDiagnostics(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); }
@ -133,7 +133,7 @@ private:
} // namespace
void ento::createHTMLDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &OutputDir, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
@ -142,37 +142,38 @@ void ento::createHTMLDiagnosticConsumer(
// 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);
createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, CTU);
// TODO: Emit an error here.
if (OutputDir.empty())
return;
C.push_back(new HTMLDiagnostics(AnalyzerOpts, OutputDir, PP, true));
C.push_back(new HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP, true));
}
void ento::createHTMLSingleFileDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &OutputDir, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, 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);
C.push_back(new HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP, false));
}
void ento::createPlistHTMLDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
PathDiagnosticConsumerOptions DiagOpts, 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,
DiagOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP,
CTU);
createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
createPlistMultiFileDiagnosticConsumer(DiagOpts, C, prefix, PP, CTU);
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, prefix, PP,
CTU);
}
//===----------------------------------------------------------------------===//
@ -245,7 +246,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
int FD;
SmallString<128> Model, ResultPath;
if (!AnalyzerOpts.ShouldWriteStableReportFilename) {
if (!DiagOpts.ShouldWriteStableReportFilename) {
llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
if (std::error_code EC =
llvm::sys::fs::make_absolute(Model)) {
@ -535,7 +536,7 @@ void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
<input type="checkbox" class="spoilerhider" id="showinvocation" />
<label for="showinvocation" >Show analyzer invocation</label>
<div class="spoiler">clang -cc1 )<<<";
os << html::EscapeText(AnalyzerOpts.FullCompilerInvocation);
os << html::EscapeText(DiagOpts.ToolInvocation);
os << R"<<<(
</div>
<div id='tooltiphint' hidden="true">

View File

@ -20,7 +20,6 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/TokenConcatenation.h"
#include "clang/Rewrite/Core/HTMLRewrite.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/IssueHash.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/SmallPtrSet.h"
@ -40,13 +39,17 @@ using namespace markup;
namespace {
class PlistDiagnostics : public PathDiagnosticConsumer {
PathDiagnosticConsumerOptions DiagOpts;
const std::string OutputFile;
const Preprocessor &PP;
const cross_tu::CrossTranslationUnitContext &CTU;
AnalyzerOptions &AnOpts;
const bool SupportsCrossFileDiagnostics;
void printBugPath(llvm::raw_ostream &o, const FIDMap &FM,
const PathPieces &Path);
public:
PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
PlistDiagnostics(PathDiagnosticConsumerOptions DiagOpts,
const std::string &OutputFile, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU,
bool supportsMultipleFiles);
@ -75,23 +78,19 @@ namespace {
/// A helper class for emitting a single report.
class PlistPrinter {
const FIDMap& FM;
AnalyzerOptions &AnOpts;
const Preprocessor &PP;
const cross_tu::CrossTranslationUnitContext &CTU;
llvm::SmallVector<const PathDiagnosticMacroPiece *, 0> MacroPieces;
public:
PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
PlistPrinter(const FIDMap& FM,
const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU)
: FM(FM), AnOpts(AnOpts), PP(PP), CTU(CTU) {
: FM(FM), PP(PP), CTU(CTU) {
}
void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P) {
ReportPiece(o, P, /*indent*/ 4, /*depth*/ 0, /*includeControlFlow*/ true);
// Don't emit a warning about an unused private field.
(void)AnOpts;
}
/// Print the expansions of the collected macro pieces.
@ -166,11 +165,6 @@ struct ExpansionInfo {
} // end of anonymous namespace
static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
AnalyzerOptions &AnOpts, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU,
const PathPieces &Path);
/// Print coverage information to output stream {@code o}.
/// May modify the used list of files {@code Fids} by inserting new ones.
static void printCoverage(const PathDiagnostic *D,
@ -521,11 +515,53 @@ static void printCoverage(const PathDiagnostic *D,
assert(IndentLevel == InputIndentLevel);
}
static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
AnalyzerOptions &AnOpts, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU,
const PathPieces &Path) {
PlistPrinter Printer(FM, AnOpts, PP, CTU);
//===----------------------------------------------------------------------===//
// Methods of PlistDiagnostics.
//===----------------------------------------------------------------------===//
PlistDiagnostics::PlistDiagnostics(
PathDiagnosticConsumerOptions DiagOpts, const std::string &output,
const Preprocessor &PP, const cross_tu::CrossTranslationUnitContext &CTU,
bool supportsMultipleFiles)
: DiagOpts(std::move(DiagOpts)), OutputFile(output), PP(PP), CTU(CTU),
SupportsCrossFileDiagnostics(supportsMultipleFiles) {
// FIXME: Will be used by a later planned change.
(void)this->CTU;
}
void ento::createPlistDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &OutputFile, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
// TODO: Emit an error here.
if (OutputFile.empty())
return;
C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU,
/*supportsMultipleFiles=*/false));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile,
PP, CTU);
}
void ento::createPlistMultiFileDiagnosticConsumer(
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &OutputFile, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
// TODO: Emit an error here.
if (OutputFile.empty())
return;
C.push_back(new PlistDiagnostics(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) {
PlistPrinter Printer(FM, PP, CTU);
assert(std::is_partitioned(Path.begin(), Path.end(),
[](const PathDiagnosticPieceRef &E) {
return E->getKind() == PathDiagnosticPiece::Note;
@ -558,7 +594,7 @@ static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
o << " </array>\n";
if (!AnOpts.ShouldDisplayMacroExpansions)
if (!DiagOpts.ShouldDisplayMacroExpansions)
return;
o << " <key>macro_expansions</key>\n"
@ -567,48 +603,6 @@ static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
o << " </array>\n";
}
//===----------------------------------------------------------------------===//
// Methods of PlistDiagnostics.
//===----------------------------------------------------------------------===//
PlistDiagnostics::PlistDiagnostics(
AnalyzerOptions &AnalyzerOpts, const std::string &output,
const Preprocessor &PP, const cross_tu::CrossTranslationUnitContext &CTU,
bool supportsMultipleFiles)
: OutputFile(output), PP(PP), CTU(CTU), AnOpts(AnalyzerOpts),
SupportsCrossFileDiagnostics(supportsMultipleFiles) {
// FIXME: Will be used by a later planned change.
(void)this->CTU;
}
void ento::createPlistDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
const std::string &OutputFile, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &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 &OutputFile, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &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) {
@ -683,7 +677,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
o << " <dict>\n";
const PathDiagnostic *D = *DI;
printBugPath(o, FM, AnOpts, PP, CTU, D->path);
printBugPath(o, FM, D->path);
// Output the bug type and bug category.
o << " <key>description</key>";
@ -807,7 +801,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
EmitString(o << " ", SM.getFileEntryForID(FID)->getName()) << '\n';
o << " </array>\n";
if (llvm::AreStatisticsEnabled() && AnOpts.ShouldSerializeStats) {
if (llvm::AreStatisticsEnabled() && DiagOpts.ShouldSerializeStats) {
o << " <key>statistics</key>\n";
std::string stats;
llvm::raw_string_ostream os(stats);

View File

@ -14,7 +14,6 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/Version.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
@ -32,8 +31,7 @@ class SarifDiagnostics : public PathDiagnosticConsumer {
const LangOptions &LO;
public:
SarifDiagnostics(AnalyzerOptions &, const std::string &Output,
const LangOptions &LO)
SarifDiagnostics(const std::string &Output, const LangOptions &LO)
: OutputFile(Output), LO(LO) {}
~SarifDiagnostics() override = default;
@ -48,7 +46,7 @@ public:
} // end anonymous namespace
void ento::createSarifDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C,
const std::string &Output, const Preprocessor &PP,
const cross_tu::CrossTranslationUnitContext &CTU) {
@ -56,8 +54,9 @@ void ento::createSarifDiagnosticConsumer(
if (Output.empty())
return;
C.push_back(new SarifDiagnostics(AnalyzerOpts, Output, PP.getLangOpts()));
createTextMinimalPathDiagnosticConsumer(AnalyzerOpts, C, Output, PP, CTU);
C.push_back(new SarifDiagnostics(Output, PP.getLangOpts()));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, Output, PP,
CTU);
}
static StringRef getFileName(const FileEntry &FE) {

View File

@ -34,20 +34,17 @@ namespace {
/// 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 {
PathDiagnosticConsumerOptions DiagOpts;
DiagnosticsEngine &DiagEng;
const LangOptions &LO;
const bool IncludePath = false;
const bool ShouldEmitAsError = false;
const bool ApplyFixIts = false;
const bool ShouldDisplayCheckerName = false;
bool ShouldDisplayPathNotes;
public:
TextDiagnostics(DiagnosticsEngine &DiagEng, const LangOptions &LO,
bool ShouldIncludePath, const AnalyzerOptions &AnOpts)
: DiagEng(DiagEng), LO(LO), IncludePath(ShouldIncludePath),
ShouldEmitAsError(AnOpts.AnalyzerWerror),
ApplyFixIts(AnOpts.ShouldApplyFixIts),
ShouldDisplayCheckerName(AnOpts.ShouldDisplayCheckerNameForText) {}
TextDiagnostics(PathDiagnosticConsumerOptions DiagOpts,
DiagnosticsEngine &DiagEng, const LangOptions &LO,
bool ShouldDisplayPathNotes)
: DiagOpts(std::move(DiagOpts)), DiagEng(DiagEng), LO(LO),
ShouldDisplayPathNotes(ShouldDisplayPathNotes) {}
~TextDiagnostics() override {}
StringRef getName() const override { return "TextDiagnostics"; }
@ -56,13 +53,13 @@ public:
bool supportsCrossFileDiagnostics() const override { return true; }
PathGenerationScheme getGenerationScheme() const override {
return IncludePath ? Minimal : None;
return ShouldDisplayPathNotes ? Minimal : None;
}
void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
FilesMade *filesMade) override {
unsigned WarnID =
ShouldEmitAsError
DiagOpts.ShouldDisplayWarningsAsErrors
? DiagEng.getCustomDiagID(DiagnosticsEngine::Error, "%0")
: DiagEng.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
unsigned NoteID = DiagEng.getCustomDiagID(DiagnosticsEngine::Note, "%0");
@ -72,7 +69,7 @@ public:
auto reportPiece = [&](unsigned ID, FullSourceLoc Loc, StringRef String,
ArrayRef<SourceRange> Ranges,
ArrayRef<FixItHint> Fixits) {
if (!ApplyFixIts) {
if (!DiagOpts.ShouldApplyFixIts) {
DiagEng.Report(Loc, ID) << String << Ranges << Fixits;
return;
}
@ -92,9 +89,10 @@ public:
E = Diags.end();
I != E; ++I) {
const PathDiagnostic *PD = *I;
std::string WarningMsg =
(ShouldDisplayCheckerName ? " [" + PD->getCheckerName() + "]" : "")
.str();
std::string WarningMsg = (DiagOpts.ShouldDisplayDiagnosticName
? " [" + PD->getCheckerName() + "]"
: "")
.str();
reportPiece(WarnID, PD->getLocation().asLocation(),
(PD->getShortDescription() + WarningMsg).str(),
@ -110,7 +108,7 @@ public:
Piece->getFixits());
}
if (!IncludePath)
if (!ShouldDisplayPathNotes)
continue;
// Then, add the path notes if necessary.
@ -125,7 +123,7 @@ public:
}
}
if (!ApplyFixIts || Repls.empty())
if (Repls.empty())
return;
Rewriter Rewrite(SM, LO);
@ -139,18 +137,19 @@ public:
} // end anonymous namespace
void ento::createTextPathDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
PathDiagnosticConsumerOptions DiagOpts, 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));
C.emplace_back(new TextDiagnostics(std::move(DiagOpts), PP.getDiagnostics(),
PP.getLangOpts(),
/*ShouldDisplayPathNotes=*/true));
}
void ento::createTextMinimalPathDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
PathDiagnosticConsumerOptions DiagOpts, 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));
C.emplace_back(new TextDiagnostics(std::move(DiagOpts), PP.getDiagnostics(),
PP.getLangOpts(),
/*ShouldDisplayPathNotes=*/false));
}

View File

@ -150,7 +150,7 @@ public:
break;
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
case PD_##NAME: \
CREATEFN(*Opts.get(), PathConsumers, OutDir, PP, CTU); \
CREATEFN(Opts->getDiagOpts(), PathConsumers, OutDir, PP, CTU); \
break;
#include "clang/StaticAnalyzer/Core/Analyses.def"
default: