================
@@ -195,6 +211,98 @@ class ErrorReporter {
}
for (const auto &Note : Error.Notes)
reportNote(Note);
+
+ if (SarifWriter)
+ exportSarifResult(Error, Loc);
+ }
+
+ CharSourceRange getNoteRange(const tooling::DiagnosticMessage &Note) {
+ if (!Note.Ranges.empty())
+ return getRange(Note.Ranges.front());
+ const SourceLocation Loc = getLocation(Note.FilePath, Note.FileOffset);
+ if (Loc.isInvalid())
+ return {};
+ return getOffsetRange(SourceMgr, Loc);
+ }
+
+ SmallVector<ThreadFlow, 8> createThreadFlows(const ClangTidyError &Error) {
+ SmallVector<ThreadFlow, 8> Flows;
+ if (!StringRef(Error.DiagnosticName).starts_with("clang-analyzer-"))
+ return Flows;
+
+ Flows.reserve(Error.Notes.size());
+ for (const tooling::DiagnosticMessage &Note : Error.Notes) {
+ Flows.push_back(ThreadFlow::create()
+ .setRange(getNoteRange(Note))
+ .setMessage(Note.Message));
+ }
+ return Flows;
+ }
+
+ void exportSarifResult(const ClangTidyError &Error,
+ const SourceLocation Loc) {
+ assert(SarifWriter &&
+ "SarifWriter must be initialized to export SARIF results");
+
+ const auto [RuleIndexEntryIt, Inserted] =
+ SarifRuleIdx.try_emplace(Error.DiagnosticName, 0);
+ size_t &RuleIndex = RuleIndexEntryIt->second;
+
+ const DiagnosticsEngine::Level EffectiveLevel =
+ Error.IsWarningAsError
+ ? DiagnosticsEngine::Error
+ : static_cast<DiagnosticsEngine::Level>(Error.DiagLevel);
+
+ if (Inserted) {
+ const StringRef Name = Error.DiagnosticName;
+ SarifRule Rule = SarifRule::create().setRuleId(Name).setName(Name);
+ Rule = addDiagnosticLevelToRule(Rule, EffectiveLevel);
+ if (SarifWriter)
+ RuleIndex = SarifWriter->createRule(Rule);
+ }
+
+ SarifResult Result =
+ SarifResult::create(RuleIndex)
+ .setDiagnosticMessage(Error.Message.Message)
+ .setDiagnosticLevel(getSarifResultLevel(EffectiveLevel))
+ .addLocations(getResultRanges(Error, Loc));
+
+ if (StringRef(Error.DiagnosticName).starts_with("clang-analyzer-")) {
+ Result = Result.setThreadFlows(createThreadFlows(Error));
+ } else {
+ for (const tooling::DiagnosticMessage &Note : Error.Notes) {
+ const CharSourceRange Range = getNoteRange(Note);
+ if (Range.isValid())
+ Result = Result.addRelatedLocations(Range, Note.Message);
+ }
+ }
+ if (SarifWriter)
+ SarifWriter->appendResult(Result);
+ }
+
+ CharSourceRange getOffsetRange(SourceManager &SM, SourceLocation Loc) {
+ const std::pair<FileID, unsigned> &DecomposedLoc =
SM.getDecomposedLoc(Loc);
+ const FileID FileId = DecomposedLoc.first;
+ const unsigned Offset = DecomposedLoc.second;
+ return CharSourceRange::getCharRange(
+ Loc, Loc.getLocWithOffset(Offset < SM.getFileIDSize(FileId) ? 1 : 0));
+ }
+
+ SmallVector<CharSourceRange, 4> getResultRanges(const ClangTidyError &Error,
+ SourceLocation Loc) {
+ SmallVector<CharSourceRange, 4> Ranges;
+ Ranges.reserve(Error.Message.Ranges.size());
+ for (const FileByteRange &FBR : Error.Message.Ranges)
----------------
matthew-j-code wrote:
Thanks, I've changed this so the results location is always the diagnostic Loc,
and notes use their own location. This leaves highlight ranges unrepresented
when Loc is valid, I'd propose keeping them separately as an
[annotations](https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790926:~:text=to%20the%20location.-,3.28.6%20annotations%20property,-A%20location%20object)
property. Ranges in another file would fall back to relatedLocations, since an
annotation can't point to a different file.
This requires extensions to Sarif.cpp/h as SarifDocumentWriter does not support
annotations at the moment.
https://github.com/llvm/llvm-project/pull/219182
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits