MLIR  20.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 
19 namespace mlir {
20 namespace pdll {
21 namespace ast {
22 class DiagnosticEngine;
23 
24 //===----------------------------------------------------------------------===//
25 // Diagnostic
26 //===----------------------------------------------------------------------===//
27 
28 /// This class provides a simple implementation of a PDLL diagnostic.
29 class Diagnostic {
30 public:
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 
59 private:
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.
84 public:
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 
111 private:
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.
140 public:
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 
173 private:
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.
Definition: Diagnostics.h:414
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
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
const HandlerFn & getHandlerFn() const
Get the current handler function of this diagnostic engine.
Definition: Diagnostic.h:161
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.
Diagnostic & operator*()
Access the internal diagnostic.
Definition: Diagnostic.h:98
void abandon()
Abandons this diagnostic so that it will no longer be reported.
Definition: Diagnostic.h:105
Include the generated interface declarations.