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