MLIR 22.0.0git
Diagnostic.h
Go to the documentation of this file.
1//===- Diagnostic.h - PDLL AST Diagnostics ----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef MLIR_TOOLS_PDLL_AST_DIAGNOSTIC_H
10#define MLIR_TOOLS_PDLL_AST_DIAGNOSTIC_H
11
12#include <string>
13#include <optional>
14
15#include "mlir/Support/LLVM.h"
16#include "llvm/ADT/FunctionExtras.h"
17#include "llvm/Support/SourceMgr.h"
18
19namespace mlir {
20namespace pdll {
21namespace ast {
23
24//===----------------------------------------------------------------------===//
25// Diagnostic
26//===----------------------------------------------------------------------===//
27
28/// This class provides a simple implementation of a PDLL diagnostic.
29class Diagnostic {
30public:
31 using Severity = llvm::SourceMgr::DiagKind;
32
33 /// Return the severity of this diagnostic.
34 Severity getSeverity() const { return severity; }
35
36 /// Return the message of this diagnostic.
37 StringRef getMessage() const { return message; }
38
39 /// Return the location of this diagnostic.
40 SMRange getLocation() const { return location; }
41
42 /// Return the notes of this diagnostic.
43 auto getNotes() const { return llvm::make_pointee_range(notes); }
44
45 /// Attach a note to this diagnostic.
46 Diagnostic &attachNote(const Twine &msg,
47 std::optional<SMRange> noteLoc = std::nullopt) {
48 assert(getSeverity() != Severity::DK_Note &&
49 "cannot attach a Note to a Note");
50 notes.emplace_back(
51 new Diagnostic(Severity::DK_Note, noteLoc.value_or(location), msg));
52 return *notes.back();
53 }
54
55 /// Allow an inflight diagnostic to be converted to 'failure', otherwise
56 /// 'success' if this is an empty diagnostic.
57 operator LogicalResult() const { return failure(); }
58
59private:
60 Diagnostic(Severity severity, SMRange loc, const Twine &msg)
61 : severity(severity), message(msg.str()), location(loc) {}
62
63 // Allow access to the constructor.
64 friend DiagnosticEngine;
65
66 /// The severity of this diagnostic.
67 Severity severity;
68 /// The message held by this diagnostic.
69 std::string message;
70 /// The raw location of this diagnostic.
71 SMRange location;
72 /// Any additional note diagnostics attached to this diagnostic.
73 std::vector<std::unique_ptr<Diagnostic>> notes;
74};
75
76//===----------------------------------------------------------------------===//
77// InFlightDiagnostic
78//===----------------------------------------------------------------------===//
79
80/// This class represents a diagnostic that is inflight and set to be reported.
81/// This allows for last minute modifications of the diagnostic before it is
82/// emitted by a DiagnosticEngine.
84public:
85 InFlightDiagnostic() = default;
87 : owner(rhs.owner), impl(std::move(rhs.impl)) {
88 // Reset the rhs diagnostic.
89 rhs.impl.reset();
90 rhs.abandon();
91 }
93 if (isInFlight())
94 report();
95 }
96
97 /// Access the internal diagnostic.
98 Diagnostic &operator*() { return *impl; }
99 Diagnostic *operator->() { return &*impl; }
100
101 /// Reports the diagnostic to the engine.
102 void report();
103
104 /// Abandons this diagnostic so that it will no longer be reported.
105 void abandon() { owner = nullptr; }
106
107 /// Allow an inflight diagnostic to be converted to 'failure', otherwise
108 /// 'success' if this is an empty diagnostic.
109 operator LogicalResult() const { return failure(isActive()); }
110
111private:
112 InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
113 InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
115 : owner(owner), impl(std::move(rhs)) {}
116
117 /// Returns true if the diagnostic is still active, i.e. it has a live
118 /// diagnostic.
119 bool isActive() const { return impl.has_value(); }
120
121 /// Returns true if the diagnostic is still in flight to be reported.
122 bool isInFlight() const { return owner; }
123
124 // Allow access to the constructor.
125 friend DiagnosticEngine;
126
127 /// The engine that this diagnostic is to report to.
128 DiagnosticEngine *owner = nullptr;
129
130 /// The raw diagnostic that is inflight to be reported.
131 std::optional<Diagnostic> impl;
132};
133
134//===----------------------------------------------------------------------===//
135// DiagnosticEngine
136//===----------------------------------------------------------------------===//
137
138/// This class manages the construction and emission of PDLL diagnostics.
140public:
141 /// A function used to handle diagnostics emitted by the engine.
142 using HandlerFn = llvm::unique_function<void(Diagnostic &)>;
143
144 /// Emit an error to the diagnostic engine.
145 InFlightDiagnostic emitError(SMRange loc, const Twine &msg) {
146 return InFlightDiagnostic(
147 this, Diagnostic(Diagnostic::Severity::DK_Error, loc, msg));
148 }
149 InFlightDiagnostic emitWarning(SMRange loc, const Twine &msg) {
150 return InFlightDiagnostic(
151 this, Diagnostic(Diagnostic::Severity::DK_Warning, loc, msg));
152 }
153
154 /// Report the given diagnostic.
155 void report(Diagnostic &&diagnostic) {
156 if (handler)
157 handler(diagnostic);
158 }
159
160 /// Get the current handler function of this diagnostic engine.
161 const HandlerFn &getHandlerFn() const { return handler; }
162
163 /// Take the current handler function, resetting the current handler to null.
165 HandlerFn oldHandler = std::move(handler);
166 handler = {};
167 return oldHandler;
168 }
169
170 /// Set the handler function for this diagnostic engine.
171 void setHandlerFn(HandlerFn &&newHandler) { handler = std::move(newHandler); }
172
173private:
174 /// The registered diagnostic handler function.
175 HandlerFn handler;
176};
177
178} // namespace ast
179} // namespace pdll
180} // namespace mlir
181
182#endif // MLIR_TOOLS_PDLL_AST_DIAGNOSTIC_H
This class is the main interface for diagnostics.
This class manages the construction and emission of PDLL diagnostics.
Definition Diagnostic.h:139
InFlightDiagnostic emitWarning(SMRange loc, const Twine &msg)
Definition Diagnostic.h:149
void setHandlerFn(HandlerFn &&newHandler)
Set the handler function for this diagnostic engine.
Definition Diagnostic.h:171
InFlightDiagnostic emitError(SMRange loc, const Twine &msg)
Emit an error to the diagnostic engine.
Definition Diagnostic.h:145
llvm::unique_function< void(Diagnostic &)> HandlerFn
A function used to handle diagnostics emitted by the engine.
Definition Diagnostic.h:142
const HandlerFn & getHandlerFn() const
Get the current handler function of this diagnostic engine.
Definition Diagnostic.h:161
void report(Diagnostic &&diagnostic)
Report the given diagnostic.
Definition Diagnostic.h:155
HandlerFn takeHandlerFn()
Take the current handler function, resetting the current handler to null.
Definition Diagnostic.h:164
This class provides a simple implementation of a PDLL diagnostic.
Definition Diagnostic.h:29
llvm::SourceMgr::DiagKind Severity
Definition Diagnostic.h:31
StringRef getMessage() const
Return the message of this diagnostic.
Definition Diagnostic.h:37
SMRange getLocation() const
Return the location of this diagnostic.
Definition Diagnostic.h:40
Severity getSeverity() const
Return the severity of this diagnostic.
Definition Diagnostic.h:34
Diagnostic & attachNote(const Twine &msg, std::optional< SMRange > noteLoc=std::nullopt)
Attach a note to this diagnostic.
Definition Diagnostic.h:46
auto getNotes() const
Return the notes of this diagnostic.
Definition Diagnostic.h:43
This class represents a diagnostic that is inflight and set to be reported.
Definition Diagnostic.h:83
InFlightDiagnostic(InFlightDiagnostic &&rhs)
Definition Diagnostic.h:86
void report()
Reports the diagnostic to the engine.
void abandon()
Abandons this diagnostic so that it will no longer be reported.
Definition Diagnostic.h:105
Diagnostic & operator*()
Access the internal diagnostic.
Definition Diagnostic.h:98
Include the generated interface declarations.