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