llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-driver
Author: anonymous (anonymouspc)
<details>
<summary>Changes</summary>
# New feature
This PR introduces **nested/indented** diagnostic message when calling with
`clang++ -fdiagnostics-format=sarif`.
In general, the user can now see a nested tree-like diagnositc, where one
`warning`/`error` mounts several `notes` (and might recursively mount more
`notes`, which seems like a tree). User may even fold the diagnostics through
some sarif viewer.
In detail, in the `.sarif` output, `runs.results.relatedLocations` originally
only represents some `In file included from...` information, but now can
`variantly` represents child notes with diagnostics.
*(Note that now the `.sarif` format of `clang++ -fdiagnostics-format=sarif` is
same to `g++ -fdiagnostics-format=sarif`).*
# Changes to codes
### `clang/include/clang/Frontend/SARIFDiagnostic.h`,
`clang/lib/Frontend/SARIFDiagnostic.cpp`
- Logically define sarif-tree.
- We know that the `clang++` diagnostics is **logically** a tree, which means
that one error/warning often corresponds to several notes (and maybe
recursively more notes). Let's take an example, a typical `clang++` diagnostics
might looks like:
```
error: invalid binary operand '+' to A and B.
note: candidate 1
note: why candidate 1 is invalid
note: candidate 2
note: why candidate 2 is invalid
error: static assertion failed.
note: in instantiation of C
note: in instantiation of D
note: concept/constraints not satisfied.
```
- Here we rewrites the logical-data-structure of sarif into a tree (see
`SARIFDiagnostic::Node`), that is:
- when the `DiagnosticRenderer` emits diagnostics, `SARIFDiagnostic`
organize them into a recursive tree;
- when the `SARIFDiagnostic` destructs, it flush them all into the
`SarifDocumentWriter`.
### `clang/include/clang/Basic/Sarif.h`, `clang/lib/Basic/Sarif.cpp`
- Physically define sarif-tree.
- **Physically**, the sarif diagnostics format has a plain structure, that is:
- one `result` may carry several `Location`s and several
`relatedLocation`s
- a `Location` is the place where error occurs, e.g. `main.cpp:3:4`,
- a `relatedLocation` is either a
- `In file included from...` location, or a
- *`child-result`*, who takes message, location, and **nesting**.
- which **logically** corresponds a `clang++` note diagnostic.
- Here, we expand the definition of `SarifResult::RelatedLocations` from
`vector<CharSourceRange>` into `vector<variant<SarifChildResult,
CharSourceRange>>`, and, at the same time update the corresponding
serialization function for `relatedLocations`.
- *(Note that GCC also makes sarif output in the same way: put child `results`
into `relatedLocations` and then mark them with `properties.nestingLevel`)*.
### `clang/lib/Frontend/SARIFDiagnosticPrinter.cpp`
- Adjust the printer logic.
- Now the `SARIFDiagnotic` flushes all the diagnostics (at one time) when it
destructs, so we need to adjust the sequence of `SARIFDiagnosticPrinter` in
order that the `Writer->endRun()` happens **after** the `SARIFDiagnostic`
flushes.
### `clang/include/clang/Basic/DiagnosticDriverKinds.td`,
`clang/lib/Driver/ToolChains/Clang.cpp`
- Disable sarif warnings.
- Currently the `-Wsarif-format-unstable` warning happens **before** the
`SARIFDiagnostic` works, This warning message will not appear in the `json`
output, instead, it triggers in text-mode before the json output. To make the
`clang++` output machine-parsable, let's remove this warning (or move this
warning into the json).
- In my perspective, after many efforts, now the sarif mode seems ok to be
used. Let's remove the `-Wsarif-format-unstable` warning.
### `clang/unittests/Basic/SarifTest.cpp`
- Update test.
- Update these corresponding test for `SARIFDiagnostic` and the
`relatedLocations` (with child results).
---
Patch is 31.78 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/174106.diff
8 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (-4)
- (modified) clang/include/clang/Basic/Sarif.h (+42-1)
- (modified) clang/include/clang/Frontend/SARIFDiagnostic.h (+64-25)
- (modified) clang/lib/Basic/Sarif.cpp (+16-2)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (-3)
- (modified) clang/lib/Frontend/SARIFDiagnostic.cpp (+194-120)
- (modified) clang/lib/Frontend/SARIFDiagnosticPrinter.cpp (+2-2)
- (modified) clang/unittests/Basic/SarifTest.cpp (+9-3)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 5cae8fb86347f..b0a31905c1930 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -851,10 +851,6 @@ def err_drv_invalid_empty_dxil_validator_version : Error<
"invalid validator version : %0; if validator major version is 0, minor "
"version must also be 0">;
-def warn_drv_sarif_format_unstable : Warning<
- "diagnostic formatting in SARIF mode is currently unstable">,
- InGroup<DiagGroup<"sarif-format-unstable">>;
-
def warn_drv_loongarch_conflicting_implied_val : Warning<
"ignoring '%0' as it conflicts with that implied by '%1' (%2)">,
InGroup<OptionIgnored>;
diff --git a/clang/include/clang/Basic/Sarif.h
b/clang/include/clang/Basic/Sarif.h
index 6f82d253876d9..56080f69a3a1d 100644
--- a/clang/include/clang/Basic/Sarif.h
+++ b/clang/include/clang/Basic/Sarif.h
@@ -295,6 +295,42 @@ class SarifRule {
}
};
+/// A SARIF child-result is
+/// - logically, a sub-result (e.g. note) belonging to a SARIF result (e.g.
error, warning)
+/// - physically, a RelatedLocation in a SARIF result (same level as "in file
included from..." locations)
+class SarifChildResult {
+ friend class clang::SarifDocumentWriter;
+
+ std::string DiagnosticMessage;
+ llvm::SmallVector<CharSourceRange> Locations;
+ int Nesting;
+ std::optional<SarifResultLevel> LevelOverride;
+
+public:
+ static SarifChildResult create() { return SarifChildResult(); }
+
+ SarifChildResult setDiagnosticMessage(llvm::StringRef Message) {
+ DiagnosticMessage = Message.str();
+ return *this;
+ }
+
+ SarifChildResult addLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) {
+#ifndef NDEBUG
+ for (const auto &Loc : DiagLocs) {
+ assert(Loc.isCharRange() &&
+ "SARIF Child Results require character granular source ranges!");
+ }
+#endif
+ Locations.append(DiagLocs.begin(), DiagLocs.end());
+ return *this;
+ }
+
+ SarifChildResult setNesting(int Nest) {
+ Nesting = Nest;
+ return *this;
+ }
+};
+
/// A SARIF result (also called a "reporting item") is a unit of output
/// produced when one of the tool's \c reportingDescriptor encounters a match
/// on the file being analysed by the tool.
@@ -325,7 +361,7 @@ class SarifResult {
std::string HostedViewerURI;
llvm::SmallDenseMap<StringRef, std::string, 4> PartialFingerprints;
llvm::SmallVector<CharSourceRange, 8> Locations;
- llvm::SmallVector<CharSourceRange, 8> RelatedLocations;
+ llvm::SmallVector<std::variant<SarifChildResult, CharSourceRange>, 8>
RelatedLocations; // A RelatedLocation is either a ChildResult or a plain "in
file included from..." Location.
llvm::SmallVector<ThreadFlow, 8> ThreadFlows;
std::optional<SarifResultLevel> LevelOverride;
@@ -378,6 +414,11 @@ class SarifResult {
return *this;
}
+ SarifResult addRelatedLocations(llvm::ArrayRef<SarifChildResult>
ChildResults) {
+ RelatedLocations.append(ChildResults.begin(), ChildResults.end());
+ return *this;
+ }
+
SarifResult setThreadFlows(llvm::ArrayRef<ThreadFlow> ThreadFlowResults) {
ThreadFlows.assign(ThreadFlowResults.begin(), ThreadFlowResults.end());
return *this;
diff --git a/clang/include/clang/Frontend/SARIFDiagnostic.h
b/clang/include/clang/Frontend/SARIFDiagnostic.h
index 7a6f27eb3b9fa..70b5c80b68812 100644
--- a/clang/include/clang/Frontend/SARIFDiagnostic.h
+++ b/clang/include/clang/Frontend/SARIFDiagnostic.h
@@ -14,9 +14,13 @@
#ifndef LLVM_CLANG_FRONTEND_SARIFDIAGNOSTIC_H
#define LLVM_CLANG_FRONTEND_SARIFDIAGNOSTIC_H
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Sarif.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Frontend/DiagnosticRenderer.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
namespace clang {
@@ -25,7 +29,7 @@ class SARIFDiagnostic : public DiagnosticRenderer {
SARIFDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
DiagnosticOptions &DiagOpts, SarifDocumentWriter *Writer);
- ~SARIFDiagnostic() = default;
+ ~SARIFDiagnostic();
SARIFDiagnostic &operator=(const SARIFDiagnostic &&) = delete;
SARIFDiagnostic(SARIFDiagnostic &&) = delete;
@@ -36,7 +40,7 @@ class SARIFDiagnostic : public DiagnosticRenderer {
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
- DiagOrStoredDiag D) override;
+ DiagOrStoredDiag Diag) override;
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
@@ -55,28 +59,63 @@ class SARIFDiagnostic : public DiagnosticRenderer {
StringRef ModuleName) override;
private:
- // Shared between SARIFDiagnosticPrinter and this renderer.
- SarifDocumentWriter *Writer;
-
- SarifResult addLocationToResult(SarifResult Result, FullSourceLoc Loc,
- PresumedLoc PLoc,
- ArrayRef<CharSourceRange> Ranges,
- const Diagnostic &Diag);
-
- SarifResult addRelatedLocationToResult(SarifResult Result, FullSourceLoc Loc,
- PresumedLoc PLoc);
-
- llvm::SmallVector<CharSourceRange>
- getSarifLocation(FullSourceLoc Loc, PresumedLoc PLoc,
- ArrayRef<CharSourceRange> Ranges);
-
- SarifRule addDiagnosticLevelToRule(SarifRule Rule,
- DiagnosticsEngine::Level Level);
-
- llvm::StringRef emitFilename(StringRef Filename, const SourceManager &SM);
-
- llvm::SmallVector<std::pair<FullSourceLoc, PresumedLoc>>
- RelatedLocationsCache;
+ class Node {
+ public:
+ // Subclasses
+ struct Result {
+ DiagnosticsEngine::Level Level;
+ std::string Message;
+ DiagOrStoredDiag Diag;
+ };
+
+ struct Option {
+ const LangOptions* LangOptsPtr;
+ const DiagnosticOptions* DiagnosticOptsPtr;
+ };
+
+ struct Location {
+ FullSourceLoc Loc;
+ PresumedLoc PLoc;
+ llvm::SmallVector<CharSourceRange> Ranges;
+
+ // Methods to construct a llvm-style location.
+ llvm::SmallVector<CharSourceRange>
getCharSourceRangesWithOption(Option);
+ };
+
+ // Constructor
+ Node(Result Result_, Option Option_, int Nesting);
+
+ // Operations on building a node-tree.
+ // Arguments and results are all in node-style.
+ Node& getParent();
+ Node& getForkableParent();
+ llvm::SmallVector<std::unique_ptr<Node>>& getChildrenPtrs();
+ Node& addChildResult(Result);
+ Node& addLocation(Location);
+ Node& addRelatedLocation(Location);
+
+ // Methods to access underlying data for other llvm-components to read
from it.
+ // Arguments and results are all in llvm-style.
+ unsigned getDiagID();
+ DiagnosticsEngine::Level getLevel();
+ std::string getDiagnosticMessage();
+ llvm::SmallVector<CharSourceRange> getLocations();
+ llvm::SmallVector<CharSourceRange> getRelatedLocations();
+ int getNesting();
+
+ private:
+ Result Result_;
+ llvm::SmallVector<Location> Locations;
+ llvm::SmallVector<Location> RelatedLocations;
+ Option Option_;
+ int Nesting;
+ Node* ParentPtr = nullptr;
+ llvm::SmallVector<std::unique_ptr<Node>> ChildrenPtrs = {};
+ };
+
+ Node Root;
+ Node* Current = &Root;
+ SarifDocumentWriter *Writer; // Shared between SARIFDiagnosticPrinter and
this renderer.
};
} // end namespace clang
diff --git a/clang/lib/Basic/Sarif.cpp b/clang/lib/Basic/Sarif.cpp
index 448de96d474af..1da7c6731d650 100644
--- a/clang/lib/Basic/Sarif.cpp
+++ b/clang/lib/Basic/Sarif.cpp
@@ -406,8 +406,22 @@ void SarifDocumentWriter::appendResult(const SarifResult
&Result) {
if (!Result.RelatedLocations.empty()) {
json::Array ReLocs;
- for (auto &Range : Result.RelatedLocations) {
- ReLocs.emplace_back(createLocation(createPhysicalLocation(Range)));
+ for (auto &RelatedLocation : Result.RelatedLocations) {
+ if (RelatedLocation.index() == 0) { // variant is a SarifChildResult
+ const SarifChildResult& ChildResult = std::get<0>(RelatedLocation);
+ json::Object Object;
+ Object.insert({"message",
createMessage(ChildResult.DiagnosticMessage)});
+ if (ChildResult.Locations.size() >= 1)
+ for (auto& kv :
createLocation(createPhysicalLocation(ChildResult.Locations[0])))
+ Object.insert({kv.getFirst(), kv.getSecond()});
+ Object.insert({
+ "properties", json::Object{{"nestingLevel", ChildResult.Nesting}}
+ });
+ ReLocs.emplace_back(std::move(Object));
+ } else { // variant is a CharSourceRange
+ const CharSourceRange& Range = std::get<1>(RelatedLocation);
+ ReLocs.emplace_back(createLocation(createPhysicalLocation(Range)));
+ }
}
Ret["relatedLocations"] = std::move(ReLocs);
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp
b/clang/lib/Driver/ToolChains/Clang.cpp
index 310f3b58a211e..38bcc12171143 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4230,9 +4230,6 @@ static void RenderDiagnosticsOptions(const Driver &D,
const ArgList &Args,
if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
CmdArgs.push_back("-fdiagnostics-format");
CmdArgs.push_back(A->getValue());
- if (StringRef(A->getValue()) == "sarif" ||
- StringRef(A->getValue()) == "SARIF")
- D.Diag(diag::warn_drv_sarif_format_unstable);
}
if (const Arg *A = Args.getLastArg(
diff --git a/clang/lib/Frontend/SARIFDiagnostic.cpp
b/clang/lib/Frontend/SARIFDiagnostic.cpp
index 2cd32ce97ea85..930d1b1383ddb 100644
--- a/clang/lib/Frontend/SARIFDiagnostic.cpp
+++ b/clang/lib/Frontend/SARIFDiagnostic.cpp
@@ -7,108 +7,210 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/SARIFDiagnostic.h"
-#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
+#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/Sarif.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Locale.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>
namespace clang {
+// In sarif mode,
+// a diagnostics 'group' have 1 top-level error/warning and several sub-level
notes.
+// For example:
+//
+// error: static assertion failed.
+// note: in instantiation of 'cat::meow'.
+// note: because concept 'paper_tiger' would be invalid.
+// error: invalid operands to binary expression 'cat::meow' and 'dog::wolf'.
+// note: candidate function not viable.
+// note: no known conversion from 'tiger::meooooow' to 'cat::meow'
+// note: candidate function ignored.
+// note: constraints not satisfied.
+// note: ... (candidates)
+// note: ... (reasons)
+// note: too many candidates.
+// error: too many errors occured, stopping now.
+
SARIFDiagnostic::SARIFDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
DiagnosticOptions &DiagOpts,
SarifDocumentWriter *Writer)
- : DiagnosticRenderer(LangOpts, DiagOpts), Writer(Writer) {}
+ : DiagnosticRenderer(LangOpts, DiagOpts),
+ Root(Node::Result(), Node::Option{&LangOpts, &DiagOpts},
/*Nesting=*/-1), // The root does not represents a diagnostic.
+ Current(&Root),
+ Writer(Writer)
+{
+ // Don't print 'X warnings and Y errors generated'.
+ DiagOpts.ShowCarets = false;
+}
+
+// helper function
+namespace {
+ template <class NodeType, class IterateFuncType, class ApplyFuncType>
+ void RecursiveFor (NodeType&& Node, IterateFuncType&& IterateFunc,
ApplyFuncType&& ApplyFunc) {
+ for (auto&& Child : IterateFunc(Node)) {
+ ApplyFunc(*Child);
+ RecursiveFor(*Child, IterateFunc, ApplyFunc);
+ }
+ }
+} // namespace
+
+SARIFDiagnostic::~SARIFDiagnostic() {
+ // clang-format off
+ for (auto& TopLevelDiagnosticsPtr : Root.getChildrenPtrs()) { // For each
top-level error/warnings.
+ unsigned DiagID = TopLevelDiagnosticsPtr->getDiagID();
+ SarifRule Rule = SarifRule::create() // Each top-level error/warning has a
corresponding Rule.
+ .setRuleId(std::to_string(DiagID))
+ .setDefaultConfiguration(
+ SarifReportingConfiguration::create()
+ .setLevel(
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Note ? SarifResultLevel::Note :
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Remark ? SarifResultLevel::Note :
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Warning ? SarifResultLevel::Warning :
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Error ? SarifResultLevel::Error :
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Fatal ? SarifResultLevel::Error :
+ (assert(false && "Invalid diagnostic
type"), SarifResultLevel::None)
+ )
+ .setRank(
+ TopLevelDiagnosticsPtr->getLevel() <=
DiagnosticsEngine::Level::Warning ? 0 :
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Error ? 50 :
+ TopLevelDiagnosticsPtr->getLevel() ==
DiagnosticsEngine::Level::Fatal ? 100 :
+ (assert(false && "Invalid diagnostic
type"), 0)
+ )
+ );
+ unsigned RuleIndex = Writer->createRule(Rule); // Write into Writer.
+
+ SarifResult Result = SarifResult::create(RuleIndex)
+ .setDiagnosticMessage(TopLevelDiagnosticsPtr->getDiagnosticMessage())
+ .addLocations(TopLevelDiagnosticsPtr->getLocations())
+ .addRelatedLocations(TopLevelDiagnosticsPtr->getRelatedLocations());
+ RecursiveFor(*TopLevelDiagnosticsPtr, [] (Node& Node) -> auto& { return
Node.getChildrenPtrs(); }, [&] (Node& Node) { // For each (recursive)
ChildResults.
+ Result.addRelatedLocations({
+ SarifChildResult::create()
+ .setDiagnosticMessage(Node.getDiagnosticMessage())
+ .addLocations(Node.getLocations())
+ .setNesting(Node.getNesting())
+ });
+ Result.addRelatedLocations(Node.getRelatedLocations());
+ });
+ Writer->appendResult(Result); // Write into Writer
+ }
+ // clang-format on
+}
-// FIXME(llvm-project/issues/57323): Refactor Diagnostic classes.
void SARIFDiagnostic::emitDiagnosticMessage(
FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
- DiagOrStoredDiag D) {
+ DiagOrStoredDiag Diag) {
- const auto *Diag = D.dyn_cast<const Diagnostic *>();
+ if (Level >= DiagnosticsEngine::Level::Warning) {
+ Current = &Root; // If this is a top-level error/warning, repoint Current
to Root.
+ } else {
+ if (Message.starts_with("candidate"))
+ Current = &Current->getForkableParent(); // If this is an forked-case
note, repoint Current to the nearest forkable Node.
+ }
+ Current = &Current->addChildResult(Node::Result{Level, std::string(Message),
Diag}); // add child to the parent error/warning/note Node.
+ Current = &Current->addLocation(Node::Location{Loc, PLoc,
llvm::SmallVector<CharSourceRange>(Ranges)});
+}
- if (!Diag)
- return;
+void SARIFDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc)
{
+ Current = &Current->addRelatedLocation(Node::Location{Loc, PLoc, {}});
+}
- SarifRule Rule =
SarifRule::create().setRuleId(std::to_string(Diag->getID()));
+void SARIFDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) {
+ Current = &Current->addRelatedLocation(Node::Location{Loc, PLoc, {}});
+}
- Rule = addDiagnosticLevelToRule(Rule, Level);
+SARIFDiagnostic::Node::Node(Result Result_, Option Option_, int Nesting)
+ : Result_(std::move(Result_)), Option_(std::move(Option_)), Nesting(Nesting)
{}
- unsigned RuleIdx = Writer->createRule(Rule);
+SARIFDiagnostic::Node& SARIFDiagnostic::Node::getParent() {
+ assert(ParentPtr && "getParent() of SARIFDiagnostic::Root!");
+ return *ParentPtr;
+}
- SarifResult Result =
- SarifResult::create(RuleIdx).setDiagnosticMessage(Message);
+SARIFDiagnostic::Node& SARIFDiagnostic::Node::getForkableParent() {
+ Node* Ptr = this;
+ while (Ptr->getLevel() <= DiagnosticsEngine::Note) // The forkable node here
"is and only is" warning/error/fatal.
+ Ptr = &Ptr->getParent();
+ return *Ptr;
+}
- if (Loc.isValid())
- Result = addLocationToResult(Result, Loc, PLoc, Ranges, *Diag);
+llvm::SmallVector<std::unique_ptr<SARIFDiagnostic::Node>>&
SARIFDiagnostic::Node::getChildrenPtrs() {
+ return ChildrenPtrs;
+}
- for (auto &[RelLoc, RelPLoc] : RelatedLocationsCache)
- Result = addRelatedLocationToResult(Result, RelLoc, RelPLoc);
- RelatedLocationsCache.clear();
+SARIFDiagnostic::Node& SARIFDiagnostic::Node::addChildResult(Result
ChildResult) {
+
ChildrenPtrs.push_back(std::make_unique<Node>(Node::Result(std::move(ChildResult)),
Node::Option(std::move(Option_)), Nesting + 1));
+ ChildrenPtrs.back()->ParentPtr = this; // I am the parent of this new child.
+ return *ChildrenPtrs.back();
+}
- Writer->appendResult(Result);
+SARIFDiagnostic::Node& SARIFDiagnostic::Node::addLocation(Location Location) {
+ Locations.push_back(std::move(Location));
+ return *this;
}
-void SARIFDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc)
{
- // We always emit include location before results, for example:
- //
- // In file included from ...
- // In file included from ...
- // error: ...
- //
- // At this time We cannot peek the SarifRule. But what we
- // do is to push it into a cache and wait for next time
- // \ref SARIFDiagnostic::emitDiagnosticMessage to pick it up.
- RelatedLocationsCache.push_back({Loc, PLoc});
+SARIFDiagnostic::Node& SARIFDiagnostic::Node::addRelatedLocation(Location
Location) {
+ RelatedLocations.push_back(std::move(Location));
+ return *this;
}
-void SARIFDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
- StringRef ModuleName) {
- RelatedLocationsCache.push_back({Loc, PLoc});
+unsigned SARIFDiagnostic::Node::getDiagID() {
+ return llvm::isa<const Diagnostic*>(Result_.Diag) ?
+ Result_.Diag.dyn_cast<const Diagnostic*>()->getID() :
+ Result_.Diag.dyn_cast<const StoredDiagnostic*>()->getID();
}
-SarifResult SARIFDiagnostic::addLocationToResult(
- SarifResult Result, FullSourceLoc Loc, PresumedLoc PLoc,
- ArrayRef<CharSourceRange> Ranges, const Diagnostic &Diag) {
- auto Locations = getSarifLocation(Loc, PLoc, Ranges);
- return Result.addLocations(Locations);
+DiagnosticsEngine::Level SARIFDiagnostic::Node::getLevel() {
+ return Result_.Level;
}
-SarifResult SARIFDiagnostic::addRelatedLocationToResult(SarifResult Result,
- FullSourceLoc Loc,
- PresumedLoc PLoc) {
- auto Locations = getSarifLocation(Loc, PLoc, {});
- return Result.addRelatedLocations(Locations);
+std::string SARIFDiagnostic::Node::getDiagnosticMessage() {
+ return Result_.Message;
}
-llvm::SmallVector<CharSourceRange>
-SARIFDiagnostic::getSarifLocation(FullSourceLoc Loc, PresumedLoc PLoc,
- ArrayRef<CharSourceRange> Ranges) {
- SmallVector<CharSourceRange> Locations = {};
+llvm::SmallVector<CharSourceRan...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/174106
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits