MLIR  19.0.0git
Diagnostics.h
Go to the documentation of this file.
1 //===- Diagnostics.h - MLIR 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 // This file defines utilities for emitting diagnostics.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_IR_DIAGNOSTICS_H
14 #define MLIR_IR_DIAGNOSTICS_H
15 
16 #include "mlir/IR/Location.h"
17 #include <functional>
18 #include <optional>
19 
20 namespace llvm {
21 class MemoryBuffer;
22 class SMLoc;
23 class SourceMgr;
24 } // namespace llvm
25 
26 namespace mlir {
27 class DiagnosticEngine;
28 struct LogicalResult;
29 class MLIRContext;
30 class Operation;
31 class OperationName;
32 class OpPrintingFlags;
33 class Type;
34 class Value;
35 
36 namespace detail {
37 struct DiagnosticEngineImpl;
38 } // namespace detail
39 
40 /// Defines the different supported severity of a diagnostic.
41 enum class DiagnosticSeverity {
42  Note,
43  Warning,
44  Error,
45  Remark,
46 };
47 
48 //===----------------------------------------------------------------------===//
49 // DiagnosticArgument
50 //===----------------------------------------------------------------------===//
51 
52 /// A variant type that holds a single argument for a diagnostic.
54 public:
55  /// Note: The constructors below are only exposed due to problems accessing
56  /// constructors from type traits, they should not be used directly by users.
57  // Construct from an Attribute.
58  explicit DiagnosticArgument(Attribute attr);
59  // Construct from a floating point number.
60  explicit DiagnosticArgument(double val)
61  : kind(DiagnosticArgumentKind::Double), doubleVal(val) {}
62  explicit DiagnosticArgument(float val) : DiagnosticArgument(double(val)) {}
63  // Construct from a signed integer.
64  template <typename T>
66  T val, std::enable_if_t<std::is_signed<T>::value &&
67  std::numeric_limits<T>::is_integer &&
68  sizeof(T) <= sizeof(int64_t)> * = nullptr)
69  : kind(DiagnosticArgumentKind::Integer), opaqueVal(int64_t(val)) {}
70  // Construct from an unsigned integer.
71  template <typename T>
73  T val, std::enable_if_t<std::is_unsigned<T>::value &&
74  std::numeric_limits<T>::is_integer &&
75  sizeof(T) <= sizeof(uint64_t)> * = nullptr)
76  : kind(DiagnosticArgumentKind::Unsigned), opaqueVal(uint64_t(val)) {}
77  // Construct from a string reference.
78  explicit DiagnosticArgument(StringRef val)
79  : kind(DiagnosticArgumentKind::String), stringVal(val) {}
80  // Construct from a Type.
81  explicit DiagnosticArgument(Type val);
82 
83  /// Enum that represents the different kinds of diagnostic arguments
84  /// supported.
86  Attribute,
87  Double,
88  Integer,
89  String,
90  Type,
91  Unsigned,
92  };
93 
94  /// Outputs this argument to a stream.
95  void print(raw_ostream &os) const;
96 
97  /// Returns the kind of this argument.
98  DiagnosticArgumentKind getKind() const { return kind; }
99 
100  /// Returns this argument as an Attribute.
101  Attribute getAsAttribute() const;
102 
103  /// Returns this argument as a double.
104  double getAsDouble() const {
106  return doubleVal;
107  }
108 
109  /// Returns this argument as a signed integer.
110  int64_t getAsInteger() const {
112  return static_cast<int64_t>(opaqueVal);
113  }
114 
115  /// Returns this argument as a string.
116  StringRef getAsString() const {
118  return stringVal;
119  }
120 
121  /// Returns this argument as a Type.
122  Type getAsType() const;
123 
124  /// Returns this argument as an unsigned integer.
125  uint64_t getAsUnsigned() const {
127  return static_cast<uint64_t>(opaqueVal);
128  }
129 
130 private:
131  friend class Diagnostic;
132 
133  /// The kind of this argument.
135 
136  /// The value of this argument.
137  union {
138  double doubleVal;
139  intptr_t opaqueVal;
140  StringRef stringVal;
141  };
142 };
143 
144 inline raw_ostream &operator<<(raw_ostream &os, const DiagnosticArgument &arg) {
145  arg.print(os);
146  return os;
147 }
148 
149 //===----------------------------------------------------------------------===//
150 // Diagnostic
151 //===----------------------------------------------------------------------===//
152 
153 /// This class contains all of the information necessary to report a diagnostic
154 /// to the DiagnosticEngine. It should generally not be constructed directly,
155 /// and instead used transitively via InFlightDiagnostic.
156 class Diagnostic {
157  using NoteVector = std::vector<std::unique_ptr<Diagnostic>>;
158 
159 public:
161  : loc(loc), severity(severity) {}
162  Diagnostic(Diagnostic &&) = default;
164 
165  /// Returns the severity of this diagnostic.
166  DiagnosticSeverity getSeverity() const { return severity; }
167 
168  /// Returns the source location for this diagnostic.
169  Location getLocation() const { return loc; }
170 
171  /// Returns the current list of diagnostic arguments.
173  ArrayRef<DiagnosticArgument> getArguments() const { return arguments; }
174 
175  /// Stream operator for inserting new diagnostic arguments.
176  template <typename Arg>
177  std::enable_if_t<!std::is_convertible<Arg, StringRef>::value &&
178  std::is_constructible<DiagnosticArgument, Arg>::value,
179  Diagnostic &>
180  operator<<(Arg &&val) {
181  arguments.push_back(DiagnosticArgument(std::forward<Arg>(val)));
182  return *this;
183  }
184  Diagnostic &operator<<(StringAttr val);
185 
186  /// Stream in a string literal.
187  Diagnostic &operator<<(const char *val) {
188  arguments.push_back(DiagnosticArgument(val));
189  return *this;
190  }
191 
192  /// Stream in a Twine argument.
193  Diagnostic &operator<<(char val);
194  Diagnostic &operator<<(const Twine &val);
195  Diagnostic &operator<<(Twine &&val);
196 
197  /// Stream in an OperationName.
199 
200  /// Stream in an Operation.
202  Diagnostic &operator<<(Operation *op) { return *this << *op; }
203  /// Append an operation with the given printing flags.
204  Diagnostic &appendOp(Operation &op, const OpPrintingFlags &flags);
205 
206  /// Stream in a Value.
208 
209  /// Stream in a range.
210  template <typename T, typename ValueT = llvm::detail::ValueOfRange<T>>
211  std::enable_if_t<!std::is_constructible<DiagnosticArgument, T>::value,
212  Diagnostic &>
213  operator<<(T &&range) {
214  return appendRange(range);
215  }
216 
217  /// Append a range to the diagnostic. The default delimiter between elements
218  /// is ','.
219  template <typename T>
220  Diagnostic &appendRange(const T &c, const char *delim = ", ") {
221  llvm::interleave(
222  c, [this](const auto &a) { *this << a; }, [&]() { *this << delim; });
223  return *this;
224  }
225 
226  /// Append arguments to the diagnostic.
227  template <typename Arg1, typename Arg2, typename... Args>
228  Diagnostic &append(Arg1 &&arg1, Arg2 &&arg2, Args &&...args) {
229  append(std::forward<Arg1>(arg1));
230  return append(std::forward<Arg2>(arg2), std::forward<Args>(args)...);
231  }
232  /// Append one argument to the diagnostic.
233  template <typename Arg>
234  Diagnostic &append(Arg &&arg) {
235  *this << std::forward<Arg>(arg);
236  return *this;
237  }
238 
239  /// Outputs this diagnostic to a stream.
240  void print(raw_ostream &os) const;
241 
242  /// Converts the diagnostic to a string.
243  std::string str() const;
244 
245  /// Attaches a note to this diagnostic. A new location may be optionally
246  /// provided, if not, then the location defaults to the one specified for this
247  /// diagnostic. Notes may not be attached to other notes.
248  Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt);
249 
250  using note_iterator = llvm::pointee_iterator<NoteVector::iterator>;
252  llvm::pointee_iterator<NoteVector::const_iterator>;
253 
254  /// Returns the notes held by this diagnostic.
256  return llvm::make_pointee_range(notes);
257  }
259  return llvm::make_pointee_range(notes);
260  }
261 
262  /// Allow a diagnostic to be converted to 'failure'.
263  operator LogicalResult() const;
264 
265  /// Allow a diagnostic to be converted to 'failure'.
266  operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
267 
268  /// Allow a diagnostic to be converted to FailureOr<T>. Always results in
269  /// 'failure' because this cast cannot possibly return an object of 'T'.
270  template <typename T>
271  operator FailureOr<T>() const {
272  return failure();
273  }
274 
275 private:
276  Diagnostic(const Diagnostic &rhs) = delete;
277  Diagnostic &operator=(const Diagnostic &rhs) = delete;
278 
279  /// The source location.
280  Location loc;
281 
282  /// The severity of this diagnostic.
283  DiagnosticSeverity severity;
284 
285  /// The current list of arguments.
287 
288  /// A list of string values used as arguments. This is used to guarantee the
289  /// liveness of non-constant strings used in diagnostics.
290  std::vector<std::unique_ptr<char[]>> strings;
291 
292  /// A list of attached notes.
293  NoteVector notes;
294 };
295 
296 inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) {
297  diag.print(os);
298  return os;
299 }
300 
301 //===----------------------------------------------------------------------===//
302 // InFlightDiagnostic
303 //===----------------------------------------------------------------------===//
304 
305 /// This class represents a diagnostic that is inflight and set to be reported.
306 /// This allows for last minute modifications of the diagnostic before it is
307 /// emitted by a DiagnosticEngine.
309 public:
310  InFlightDiagnostic() = default;
312  : owner(rhs.owner), impl(std::move(rhs.impl)) {
313  // Reset the rhs diagnostic.
314  rhs.impl.reset();
315  rhs.abandon();
316  }
318  if (isInFlight())
319  report();
320  }
321 
322  /// Stream operator for new diagnostic arguments.
323  template <typename Arg>
325  return append(std::forward<Arg>(arg));
326  }
327  template <typename Arg>
328  InFlightDiagnostic &&operator<<(Arg &&arg) && {
329  return std::move(append(std::forward<Arg>(arg)));
330  }
331 
332  /// Append arguments to the diagnostic.
333  template <typename... Args>
334  InFlightDiagnostic &append(Args &&...args) & {
335  assert(isActive() && "diagnostic not active");
336  if (isInFlight())
337  impl->append(std::forward<Args>(args)...);
338  return *this;
339  }
340  template <typename... Args>
341  InFlightDiagnostic &&append(Args &&...args) && {
342  return std::move(append(std::forward<Args>(args)...));
343  }
344 
345  /// Attaches a note to this diagnostic.
346  Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt) {
347  assert(isActive() && "diagnostic not active");
348  return impl->attachNote(noteLoc);
349  }
350 
351  /// Returns the underlying diagnostic or nullptr if this diagnostic isn't
352  /// active.
353  Diagnostic *getUnderlyingDiagnostic() { return impl ? &*impl : nullptr; }
354 
355  /// Reports the diagnostic to the engine.
356  void report();
357 
358  /// Abandons this diagnostic so that it will no longer be reported.
359  void abandon();
360 
361  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
362  /// 'success' if this is an empty diagnostic.
363  operator LogicalResult() const;
364 
365  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
366  /// 'success' if this is an empty diagnostic.
367  operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
368 
369  /// Allow an inflight diagnostic to be converted to FailureOr<T>. Always
370  /// results in 'failure' because this cast cannot possibly return an object of
371  /// 'T'.
372  template <typename T>
373  operator FailureOr<T>() const {
374  return failure();
375  }
376 
377 private:
378  InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
379  InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
381  : owner(owner), impl(std::move(rhs)) {}
382 
383  /// Returns true if the diagnostic is still active, i.e. it has a live
384  /// diagnostic.
385  bool isActive() const { return impl.has_value(); }
386 
387  /// Returns true if the diagnostic is still in flight to be reported.
388  bool isInFlight() const { return owner; }
389 
390  // Allow access to the constructor.
391  friend DiagnosticEngine;
392 
393  /// The engine that this diagnostic is to report to.
394  DiagnosticEngine *owner = nullptr;
395 
396  /// The raw diagnostic that is inflight to be reported.
397  std::optional<Diagnostic> impl;
398 };
399 
400 //===----------------------------------------------------------------------===//
401 // DiagnosticEngine
402 //===----------------------------------------------------------------------===//
403 
404 /// This class is the main interface for diagnostics. The DiagnosticEngine
405 /// manages the registration of diagnostic handlers as well as the core API for
406 /// diagnostic emission. This class should not be constructed directly, but
407 /// instead interfaced with via an MLIRContext instance.
409 public:
411 
412  // Diagnostic handler registration and use. MLIR supports the ability for the
413  // IR to carry arbitrary metadata about operation location information. If a
414  // problem is detected by the compiler, it can invoke the emitError /
415  // emitWarning / emitRemark method on an Operation and have it get reported
416  // through this interface.
417  //
418  // Tools using MLIR are encouraged to register error handlers and define a
419  // schema for their location information. If they don't, then warnings and
420  // notes will be dropped and errors will be emitted to errs.
421 
422  /// The handler type for MLIR diagnostics. This function takes a diagnostic as
423  /// input, and returns success if the handler has fully processed this
424  /// diagnostic. Returns failure otherwise.
425  using HandlerTy = llvm::unique_function<LogicalResult(Diagnostic &)>;
426 
427  /// A handle to a specific registered handler object.
428  using HandlerID = uint64_t;
429 
430  /// Register a new handler for diagnostics to the engine. Diagnostics are
431  /// process by handlers in stack-like order, meaning that the last added
432  /// handlers will process diagnostics first. This function returns a unique
433  /// identifier for the registered handler, which can be used to unregister
434  /// this handler at a later time.
436 
437  /// Set the diagnostic handler with a function that returns void. This is a
438  /// convenient wrapper for handlers that always completely process the given
439  /// diagnostic.
440  template <typename FuncTy, typename RetT = decltype(std::declval<FuncTy>()(
441  std::declval<Diagnostic &>()))>
442  std::enable_if_t<std::is_same<RetT, void>::value, HandlerID>
443  registerHandler(FuncTy &&handler) {
444  return registerHandler([=](Diagnostic &diag) {
445  handler(diag);
446  return success();
447  });
448  }
449 
450  /// Erase the registered diagnostic handler with the given identifier.
451  void eraseHandler(HandlerID id);
452 
453  /// Create a new inflight diagnostic with the given location and severity.
455  assert(severity != DiagnosticSeverity::Note &&
456  "notes should not be emitted directly");
457  return InFlightDiagnostic(this, Diagnostic(loc, severity));
458  }
459 
460  /// Emit a diagnostic using the registered issue handler if present, or with
461  /// the default behavior if not. The diagnostic instance is consumed in the
462  /// process.
463  void emit(Diagnostic &&diag);
464 
465 private:
466  friend class MLIRContextImpl;
468 
469  /// The internal implementation of the DiagnosticEngine.
470  std::unique_ptr<detail::DiagnosticEngineImpl> impl;
471 };
472 
473 /// Utility method to emit an error message using this location.
475 InFlightDiagnostic emitError(Location loc, const Twine &message);
476 
477 /// Utility method to emit a warning message using this location.
479 InFlightDiagnostic emitWarning(Location loc, const Twine &message);
480 
481 /// Utility method to emit a remark message using this location.
483 InFlightDiagnostic emitRemark(Location loc, const Twine &message);
484 
485 /// Overloads of the above emission functions that take an optionally null
486 /// location. If the location is null, no diagnostic is emitted and a failure is
487 /// returned. Given that the provided location may be null, these methods take
488 /// the diagnostic arguments directly instead of relying on the returned
489 /// InFlightDiagnostic.
490 template <typename... Args>
491 LogicalResult emitOptionalError(std::optional<Location> loc, Args &&...args) {
492  if (loc)
493  return emitError(*loc).append(std::forward<Args>(args)...);
494  return failure();
495 }
496 template <typename... Args>
497 LogicalResult emitOptionalWarning(std::optional<Location> loc, Args &&...args) {
498  if (loc)
499  return emitWarning(*loc).append(std::forward<Args>(args)...);
500  return failure();
501 }
502 template <typename... Args>
503 LogicalResult emitOptionalRemark(std::optional<Location> loc, Args &&...args) {
504  if (loc)
505  return emitRemark(*loc).append(std::forward<Args>(args)...);
506  return failure();
507 }
508 
509 //===----------------------------------------------------------------------===//
510 // ScopedDiagnosticHandler
511 //===----------------------------------------------------------------------===//
512 
513 /// This diagnostic handler is a simple RAII class that registers and erases a
514 /// diagnostic handler on a given context. This class can be either be used
515 /// directly, or in conjunction with a derived diagnostic handler.
517 public:
518  explicit ScopedDiagnosticHandler(MLIRContext *ctx) : handlerID(0), ctx(ctx) {}
519  template <typename FuncTy>
520  ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
521  : handlerID(0), ctx(ctx) {
522  setHandler(std::forward<FuncTy>(handler));
523  }
525 
526 protected:
527  /// Set the handler to manage via RAII.
528  template <typename FuncTy>
529  void setHandler(FuncTy &&handler) {
530  auto &diagEngine = ctx->getDiagEngine();
531  if (handlerID)
532  diagEngine.eraseHandler(handlerID);
533  handlerID = diagEngine.registerHandler(std::forward<FuncTy>(handler));
534  }
535 
536 private:
537  /// The unique id for the scoped handler.
538  DiagnosticEngine::HandlerID handlerID;
539 
540  /// The context to erase the handler from.
541  MLIRContext *ctx;
542 };
543 
544 //===----------------------------------------------------------------------===//
545 // SourceMgrDiagnosticHandler
546 //===----------------------------------------------------------------------===//
547 
548 namespace detail {
549 struct SourceMgrDiagnosticHandlerImpl;
550 } // namespace detail
551 
552 /// This class is a utility diagnostic handler for use with llvm::SourceMgr.
554 public:
555  /// This type represents a functor used to filter out locations when printing
556  /// a diagnostic. It should return true if the provided location is okay to
557  /// display, false otherwise. If all locations in a diagnostic are filtered
558  /// out, the first location is used as the sole location. When deciding
559  /// whether or not to filter a location, this function should not recurse into
560  /// any nested location. This recursion is handled automatically by the
561  /// caller.
562  using ShouldShowLocFn = llvm::unique_function<bool(Location)>;
563 
564  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
565  raw_ostream &os,
567  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
570 
571  /// Emit the given diagnostic information with the held source manager.
572  void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
573  bool displaySourceLine = true);
574 
575 protected:
576  /// Emit the given diagnostic with the held source manager.
578 
579  /// Get a memory buffer for the given file, or nullptr if no file is
580  /// available.
581  const llvm::MemoryBuffer *getBufferForFile(StringRef filename);
582 
583  /// The source manager that we are wrapping.
584  llvm::SourceMgr &mgr;
585 
586  /// The output stream to use when printing diagnostics.
587  raw_ostream &os;
588 
589  /// A functor used when determining if a location for a diagnostic should be
590  /// shown. If null, all locations should be shown.
592 
593 private:
594  /// Convert a location into the given memory buffer into an SMLoc.
595  SMLoc convertLocToSMLoc(FileLineColLoc loc);
596 
597  /// Given a location, returns the first nested location (including 'loc') that
598  /// can be shown to the user.
599  std::optional<Location> findLocToShow(Location loc);
600 
601  /// The maximum depth that a call stack will be printed.
602  /// TODO: This should be a tunable flag.
603  unsigned callStackLimit = 10;
604 
605  std::unique_ptr<detail::SourceMgrDiagnosticHandlerImpl> impl;
606 };
607 
608 //===----------------------------------------------------------------------===//
609 // SourceMgrDiagnosticVerifierHandler
610 //===----------------------------------------------------------------------===//
611 
612 namespace detail {
613 struct SourceMgrDiagnosticVerifierHandlerImpl;
614 } // namespace detail
615 
616 /// This class is a utility diagnostic handler for use with llvm::SourceMgr that
617 /// verifies that emitted diagnostics match 'expected-*' lines on the
618 /// corresponding line of the source file.
620 public:
621  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
622  raw_ostream &out);
623  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx);
625 
626  /// Returns the status of the handler and verifies that all expected
627  /// diagnostics were emitted. This return success if all diagnostics were
628  /// verified correctly, failure otherwise.
630 
631 private:
632  /// Process a single diagnostic.
633  void process(Diagnostic &diag);
634 
635  /// Process a FileLineColLoc diagnostic.
636  void process(FileLineColLoc loc, StringRef msg, DiagnosticSeverity kind);
637 
638  std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
639 };
640 
641 //===----------------------------------------------------------------------===//
642 // ParallelDiagnosticHandler
643 //===----------------------------------------------------------------------===//
644 
645 namespace detail {
646 struct ParallelDiagnosticHandlerImpl;
647 } // namespace detail
648 
649 /// This class is a utility diagnostic handler for use when multi-threading some
650 /// part of the compiler where diagnostics may be emitted. This handler ensures
651 /// a deterministic ordering to the emitted diagnostics that mirrors that of a
652 /// single-threaded compilation.
654 public:
657 
658  /// Set the order id for the current thread. This is required to be set by
659  /// each thread that will be emitting diagnostics to this handler. The orderID
660  /// corresponds to the order in which diagnostics would be emitted when
661  /// executing synchronously. For example, if we were processing a list
662  /// of operations [a, b, c] on a single-thread. Diagnostics emitted while
663  /// processing operation 'a' would be emitted before those for 'b' or 'c'.
664  /// This corresponds 1-1 with the 'orderID'. The thread that is processing 'a'
665  /// should set the orderID to '0'; the thread processing 'b' should set it to
666  /// '1'; and so on and so forth. This provides a way for the handler to
667  /// deterministically order the diagnostics that it receives given the thread
668  /// that it is receiving on.
669  void setOrderIDForThread(size_t orderID);
670 
671  /// Remove the order id for the current thread. This removes the thread from
672  /// diagnostics tracking.
673  void eraseOrderIDForThread();
674 
675 private:
676  std::unique_ptr<detail::ParallelDiagnosticHandlerImpl> impl;
677 };
678 } // namespace mlir
679 
680 #endif
static std::string diag(const llvm::Value &value)
Attributes are known-constant values of operations.
Definition: Attributes.h:25
A variant type that holds a single argument for a diagnostic.
Definition: Diagnostics.h:53
DiagnosticArgumentKind
Enum that represents the different kinds of diagnostic arguments supported.
Definition: Diagnostics.h:85
StringRef getAsString() const
Returns this argument as a string.
Definition: Diagnostics.h:116
double getAsDouble() const
Returns this argument as a double.
Definition: Diagnostics.h:104
DiagnosticArgument(Attribute attr)
Note: The constructors below are only exposed due to problems accessing constructors from type traits...
Definition: Diagnostics.cpp:35
Type getAsType() const
Returns this argument as a Type.
Definition: Diagnostics.cpp:52
int64_t getAsInteger() const
Returns this argument as a signed integer.
Definition: Diagnostics.h:110
DiagnosticArgument(double val)
Definition: Diagnostics.h:60
DiagnosticArgumentKind getKind() const
Returns the kind of this argument.
Definition: Diagnostics.h:98
Attribute getAsAttribute() const
Returns this argument as an Attribute.
Definition: Diagnostics.cpp:45
DiagnosticArgument(T val, std::enable_if_t< std::is_unsigned< T >::value &&std::numeric_limits< T >::is_integer &&sizeof(T)<=sizeof(uint64_t)> *=nullptr)
Definition: Diagnostics.h:72
void print(raw_ostream &os) const
Outputs this argument to a stream.
Definition: Diagnostics.cpp:58
DiagnosticArgument(float val)
Definition: Diagnostics.h:62
uint64_t getAsUnsigned() const
Returns this argument as an unsigned integer.
Definition: Diagnostics.h:125
DiagnosticArgument(StringRef val)
Definition: Diagnostics.h:78
DiagnosticArgument(T val, std::enable_if_t< std::is_signed< T >::value &&std::numeric_limits< T >::is_integer &&sizeof(T)<=sizeof(int64_t)> *=nullptr)
Definition: Diagnostics.h:65
This class is the main interface for diagnostics.
Definition: Diagnostics.h:408
uint64_t HandlerID
A handle to a specific registered handler object.
Definition: Diagnostics.h:428
InFlightDiagnostic emit(Location loc, DiagnosticSeverity severity)
Create a new inflight diagnostic with the given location and severity.
Definition: Diagnostics.h:454
std::enable_if_t< std::is_same< RetT, void >::value, HandlerID > registerHandler(FuncTy &&handler)
Set the diagnostic handler with a function that returns void.
Definition: Diagnostics.h:443
void eraseHandler(HandlerID id)
Erase the registered diagnostic handler with the given identifier.
llvm::unique_function< LogicalResult(Diagnostic &)> HandlerTy
The handler type for MLIR diagnostics.
Definition: Diagnostics.h:425
HandlerID registerHandler(HandlerTy handler)
Register a new handler for diagnostics to the engine.
This class contains all of the information necessary to report a diagnostic to the DiagnosticEngine.
Definition: Diagnostics.h:156
DiagnosticSeverity getSeverity() const
Returns the severity of this diagnostic.
Definition: Diagnostics.h:166
std::string str() const
Converts the diagnostic to a string.
iterator_range< note_iterator > getNotes()
Returns the notes held by this diagnostic.
Definition: Diagnostics.h:255
Diagnostic & operator<<(Operation *op)
Definition: Diagnostics.h:202
Diagnostic & append(Arg1 &&arg1, Arg2 &&arg2, Args &&...args)
Append arguments to the diagnostic.
Definition: Diagnostics.h:228
Location getLocation() const
Returns the source location for this diagnostic.
Definition: Diagnostics.h:169
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
Diagnostic & appendRange(const T &c, const char *delim=", ")
Append a range to the diagnostic.
Definition: Diagnostics.h:220
Diagnostic & operator=(Diagnostic &&)=default
llvm::pointee_iterator< NoteVector::iterator > note_iterator
Definition: Diagnostics.h:250
MutableArrayRef< DiagnosticArgument > getArguments()
Returns the current list of diagnostic arguments.
Definition: Diagnostics.h:172
Diagnostic(Location loc, DiagnosticSeverity severity)
Definition: Diagnostics.h:160
std::enable_if_t<!std::is_constructible< DiagnosticArgument, T >::value, Diagnostic & > operator<<(T &&range)
Stream in a range.
Definition: Diagnostics.h:213
llvm::pointee_iterator< NoteVector::const_iterator > const_note_iterator
Definition: Diagnostics.h:252
Diagnostic & append(Arg &&arg)
Append one argument to the diagnostic.
Definition: Diagnostics.h:234
iterator_range< const_note_iterator > getNotes() const
Definition: Diagnostics.h:258
std::enable_if_t<!std::is_convertible< Arg, StringRef >::value &&std::is_constructible< DiagnosticArgument, Arg >::value, Diagnostic & > operator<<(Arg &&val)
Stream operator for inserting new diagnostic arguments.
Definition: Diagnostics.h:180
ArrayRef< DiagnosticArgument > getArguments() const
Definition: Diagnostics.h:173
Diagnostic & operator<<(const char *val)
Stream in a string literal.
Definition: Diagnostics.h:187
Diagnostic(Diagnostic &&)=default
void print(raw_ostream &os) const
Outputs this diagnostic to a stream.
Diagnostic & appendOp(Operation &op, const OpPrintingFlags &flags)
Append an operation with the given printing flags.
This class provides support for representing a failure result, or a valid value of type T.
Definition: LogicalResult.h:78
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:308
InFlightDiagnostic && operator<<(Arg &&arg) &&
Definition: Diagnostics.h:328
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
Definition: Diagnostics.h:346
InFlightDiagnostic & operator<<(Arg &&arg) &
Stream operator for new diagnostic arguments.
Definition: Diagnostics.h:324
InFlightDiagnostic & append(Args &&...args) &
Append arguments to the diagnostic.
Definition: Diagnostics.h:334
InFlightDiagnostic && append(Args &&...args) &&
Definition: Diagnostics.h:341
void report()
Reports the diagnostic to the engine.
Diagnostic * getUnderlyingDiagnostic()
Returns the underlying diagnostic or nullptr if this diagnostic isn't active.
Definition: Diagnostics.h:353
InFlightDiagnostic(InFlightDiagnostic &&rhs)
Definition: Diagnostics.h:311
void abandon()
Abandons this diagnostic so that it will no longer be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
This is the implementation of the MLIRContext class, using the pImpl idiom.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
DiagnosticEngine & getDiagEngine()
Returns the diagnostic engine for this context.
Set of flags used to control the behavior of the various IR print methods (e.g.
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class is a utility diagnostic handler for use when multi-threading some part of the compiler whe...
Definition: Diagnostics.h:653
void eraseOrderIDForThread()
Remove the order id for the current thread.
ParallelDiagnosticHandler(MLIRContext *ctx)
void setOrderIDForThread(size_t orderID)
Set the order id for the current thread.
This class represents success/failure for parsing-like operations that find it important to chain tog...
This diagnostic handler is a simple RAII class that registers and erases a diagnostic handler on a gi...
Definition: Diagnostics.h:516
ScopedDiagnosticHandler(MLIRContext *ctx)
Definition: Diagnostics.h:518
ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
Definition: Diagnostics.h:520
void setHandler(FuncTy &&handler)
Set the handler to manage via RAII.
Definition: Diagnostics.h:529
This class is a utility diagnostic handler for use with llvm::SourceMgr.
Definition: Diagnostics.h:553
void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind, bool displaySourceLine=true)
Emit the given diagnostic information with the held source manager.
raw_ostream & os
The output stream to use when printing diagnostics.
Definition: Diagnostics.h:587
SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx, raw_ostream &os, ShouldShowLocFn &&shouldShowLocFn={})
ShouldShowLocFn shouldShowLocFn
A functor used when determining if a location for a diagnostic should be shown.
Definition: Diagnostics.h:591
const llvm::MemoryBuffer * getBufferForFile(StringRef filename)
Get a memory buffer for the given file, or nullptr if no file is available.
llvm::SourceMgr & mgr
The source manager that we are wrapping.
Definition: Diagnostics.h:584
llvm::unique_function< bool(Location)> ShouldShowLocFn
This type represents a functor used to filter out locations when printing a diagnostic.
Definition: Diagnostics.h:562
This class is a utility diagnostic handler for use with llvm::SourceMgr that verifies that emitted di...
Definition: Diagnostics.h:619
LogicalResult verify()
Returns the status of the handler and verifies that all expected diagnostics were emitted.
SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out)
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
Include the generated interface declarations.
Definition: CallGraph.h:229
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
InFlightDiagnostic emitWarning(Location loc)
Utility method to emit a warning message using this location.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
Definition: Diagnostics.h:41
LogicalResult emitOptionalRemark(std::optional< Location > loc, Args &&...args)
Definition: Diagnostics.h:503
LogicalResult emitOptionalError(std::optional< Location > loc, Args &&...args)
Overloads of the above emission functions that take an optionally null location.
Definition: Diagnostics.h:491
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
InFlightDiagnostic emitRemark(Location loc)
Utility method to emit a remark message using this location.
LogicalResult emitOptionalWarning(std::optional< Location > loc, Args &&...args)
Definition: Diagnostics.h:497
@ String
A string value.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26