21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/StringMap.h"
23 #include "llvm/Support/ConvertUTF.h"
24 #include "llvm/Support/JSON.h"
25 #include "llvm/Support/Path.h"
28 using namespace clang;
33 std::string OutputFile;
38 SarifDiagnostics(
const std::string &Output,
const LangOptions &LO,
40 : OutputFile(Output), LO(LO), SarifWriter(
SM) {}
41 ~SarifDiagnostics()
override =
default;
43 void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
44 FilesMade *FM)
override;
46 StringRef
getName()
const override {
return "SarifDiagnostics"; }
47 PathGenerationScheme getGenerationScheme()
const override {
return Minimal; }
48 bool supportsLogicalOpControlFlow()
const override {
return true; }
49 bool supportsCrossFileDiagnostics()
const override {
return true; }
53 void ento::createSarifDiagnosticConsumer(
65 createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, Output, PP,
66 CTU, MacroExpansions);
70 return llvm::StringSwitch<StringRef>(CheckName)
72 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
73 .Case(FULLNAME, HELPTEXT)
74 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
81 return llvm::StringSwitch<StringRef>(CheckName)
83 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
84 .Case(FULLNAME, DOC_URI)
85 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
95 case PathDiagnosticPiece::Macro:
97 case PathDiagnosticPiece::PopUp:
100 case PathDiagnosticPiece::Event:
101 return Piece.
getTagStr() ==
"ConditionBRVisitor"
102 ? ThreadFlowImportance::Important
103 : ThreadFlowImportance::Essential;
104 case PathDiagnosticPiece::ControlFlow:
105 return ThreadFlowImportance::Unimportant;
107 return ThreadFlowImportance::Unimportant;
118 return CharSourceRange::getCharRange(R);
125 Lexer::getLocForEndOfToken(R.
getEnd(), 0,
SM, LO);
126 return CharSourceRange::getCharRange(BeginCharLoc, EndCharLoc);
133 for (
const auto &Piece : Pieces) {
135 Piece->getLocation().asRange(), Piece->getLocation().getManager(), LO);
139 .setMessage(Piece->getString());
140 Flows.push_back(Flow);
145 static StringMap<uint32_t>
148 StringMap<uint32_t> RuleMapping;
149 llvm::StringSet<> Seen;
152 StringRef CheckName = D->getCheckerName();
153 std::pair<llvm::StringSet<>::iterator,
bool>
P = Seen.insert(CheckName);
157 .setRuleId(CheckName)
160 size_t RuleIdx = SarifWriter.
createRule(Rule);
161 RuleMapping[CheckName] = RuleIdx;
168 const StringMap<uint32_t> &RuleMapping,
171 StringRef CheckName =
Diag->getCheckerName();
172 uint32_t RuleIdx = RuleMapping.lookup(CheckName);
174 Diag->getLocation().asRange(),
Diag->getLocation().getManager(), LO);
178 .setRuleId(CheckName)
179 .setDiagnosticMessage(
Diag->getVerboseDescription())
181 .setLocations({
Range})
182 .setThreadFlows(Flows);
186 void SarifDiagnostics::FlushDiagnosticsImpl(
187 std::vector<const PathDiagnostic *> &Diags, FilesMade *) {
194 llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_TextWithCRLF);
196 llvm::errs() <<
"warning: could not create file: " << EC.message() <<
'\n';
201 SarifWriter.createRun(
"clang",
"clang static analyzer", ToolVersion);
205 SarifWriter.appendResult(Result);
207 auto Document = SarifWriter.createDocument();
208 OS << llvm::formatv(
"{0:2}\n", json::Value(std::move(Document)));
Defines the clang::FileManager interface and associated types.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::Preprocessor interface.
static std::string getName(const CallEvent &Call)
static StringRef getRuleHelpURIStr(StringRef CheckName)
static CharSourceRange convertTokenRangeToCharRange(const SourceRange &R, const SourceManager &SM, const LangOptions &LO)
Accepts a SourceRange corresponding to a pair of the first and last tokens and converts to a Characte...
static StringRef getRuleDescription(StringRef CheckName)
static SarifResult createResult(const PathDiagnostic *Diag, const StringMap< uint32_t > &RuleMapping, const LangOptions &LO)
static ThreadFlowImportance calculateImportance(const PathDiagnosticPiece &Piece)
static StringMap< uint32_t > createRuleMapping(const std::vector< const PathDiagnostic * > &Diags, SarifDocumentWriter &SarifWriter)
static SmallVector< ThreadFlow, 8 > createThreadFlows(const PathDiagnostic *Diag, const LangOptions &LO)
Defines clang::SarifDocumentWriter, clang::SarifRule, clang::SarifResult.
Defines the SourceManager interface.
Defines version macros and version-related utility functions for Clang.
Represents a character-granular source range.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
MacroExpansionContext tracks the macro expansions processed by the Preprocessor.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
This class handles creating a valid SARIF document given various input attributes.
size_t createRule(const SarifRule &Rule)
Associate the given rule with the current run.
A SARIF result (also called a "reporting item") is a unit of output produced when one of the tool's r...
Encodes a location in the source.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
This class is used for tools that requires cross translation unit capability.
StringRef getTagStr() const
Return the string representation of the tag.
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
A Range represents the closed range [from, to].
std::vector< PathDiagnosticConsumer * > PathDiagnosticConsumers
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
The JSON file list parser is used to communicate input to InstallAPI.
std::string getClangFullVersion()
Retrieves a string representing the complete clang version, which includes the clang version number,...
Diagnostic wrappers for TextAPI types for error reporting.
These options tweak the behavior of path diangostic consumers.