MLIR  22.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 OpWithFlags;
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  template <size_t n>
188  Diagnostic &operator<<(const char (&val)[n]) {
189  arguments.push_back(DiagnosticArgument(val));
190  return *this;
191  }
192 
193  /// Stream in a Twine argument.
194  Diagnostic &operator<<(char val);
195  Diagnostic &operator<<(const Twine &val);
196  Diagnostic &operator<<(Twine &&val);
197 
198  /// Stream in an OperationName.
200 
201  /// Stream in an Operation.
204  Diagnostic &operator<<(Operation *op) { return *this << *op; }
205  /// Append an operation with the given printing flags.
206  Diagnostic &appendOp(Operation &op, const OpPrintingFlags &flags);
207 
208  /// Stream in a Value.
210 
211  /// Stream in a range.
212  template <typename T, typename ValueT = llvm::detail::ValueOfRange<T>>
213  std::enable_if_t<!std::is_constructible<DiagnosticArgument, T>::value,
214  Diagnostic &>
215  operator<<(T &&range) {
216  return appendRange(range);
217  }
218 
219  /// Append a range to the diagnostic. The default delimiter between elements
220  /// is ','.
221  template <typename T>
222  Diagnostic &appendRange(const T &c, const char *delim = ", ") {
223  llvm::interleave(
224  c, [this](const auto &a) { *this << a; }, [&]() { *this << delim; });
225  return *this;
226  }
227 
228  /// Append arguments to the diagnostic.
229  template <typename Arg1, typename Arg2, typename... Args>
230  Diagnostic &append(Arg1 &&arg1, Arg2 &&arg2, Args &&...args) {
231  append(std::forward<Arg1>(arg1));
232  return append(std::forward<Arg2>(arg2), std::forward<Args>(args)...);
233  }
234  /// Append one argument to the diagnostic.
235  template <typename Arg>
236  Diagnostic &append(Arg &&arg) {
237  *this << std::forward<Arg>(arg);
238  return *this;
239  }
240 
241  /// Outputs this diagnostic to a stream.
242  void print(raw_ostream &os) const;
243 
244  /// Converts the diagnostic to a string.
245  std::string str() const;
246 
247  /// Attaches a note to this diagnostic. A new location may be optionally
248  /// provided, if not, then the location defaults to the one specified for this
249  /// diagnostic. Notes may not be attached to other notes.
250  Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt);
251 
252  using note_iterator = llvm::pointee_iterator<NoteVector::iterator>;
254  llvm::pointee_iterator<NoteVector::const_iterator>;
255 
256  /// Returns the notes held by this diagnostic.
258  return llvm::make_pointee_range(notes);
259  }
261  return llvm::make_pointee_range(notes);
262  }
263 
264  /// Allow a diagnostic to be converted to 'failure'.
265  operator LogicalResult() const;
266 
267  /// Allow a diagnostic to be converted to 'failure'.
268  operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
269 
270  /// Allow a diagnostic to be converted to FailureOr<T>. Always results in
271  /// 'failure' because this cast cannot possibly return an object of 'T'.
272  template <typename T>
273  operator FailureOr<T>() const {
274  return failure();
275  }
276 
277  /// Returns the current list of diagnostic metadata.
279 
280 private:
281  Diagnostic(const Diagnostic &rhs) = delete;
282  Diagnostic &operator=(const Diagnostic &rhs) = delete;
283 
284  /// The source location.
285  Location loc;
286 
287  /// The severity of this diagnostic.
288  DiagnosticSeverity severity;
289 
290  /// The current list of arguments.
292 
293  /// A list of string values used as arguments. This is used to guarantee the
294  /// liveness of non-constant strings used in diagnostics.
295  std::vector<std::unique_ptr<char[]>> strings;
296 
297  /// A list of attached notes.
298  NoteVector notes;
299 
300  /// A list of metadata attached to this Diagnostic.
302 };
303 
304 inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) {
305  diag.print(os);
306  return os;
307 }
308 
309 //===----------------------------------------------------------------------===//
310 // InFlightDiagnostic
311 //===----------------------------------------------------------------------===//
312 
313 /// This class represents a diagnostic that is inflight and set to be reported.
314 /// This allows for last minute modifications of the diagnostic before it is
315 /// emitted by a DiagnosticEngine.
317 public:
318  InFlightDiagnostic() = default;
320  : owner(rhs.owner), impl(std::move(rhs.impl)) {
321  // Reset the rhs diagnostic.
322  rhs.impl.reset();
323  rhs.abandon();
324  }
326  if (isInFlight())
327  report();
328  }
329 
330  /// Stream operator for new diagnostic arguments.
331  template <typename Arg>
333  return append(std::forward<Arg>(arg));
334  }
335  template <typename Arg>
336  InFlightDiagnostic &&operator<<(Arg &&arg) && {
337  return std::move(append(std::forward<Arg>(arg)));
338  }
339 
340  /// Append arguments to the diagnostic.
341  template <typename... Args>
342  InFlightDiagnostic &append(Args &&...args) & {
343  assert(isActive() && "diagnostic not active");
344  if (isInFlight())
345  impl->append(std::forward<Args>(args)...);
346  return *this;
347  }
348  template <typename... Args>
349  InFlightDiagnostic &&append(Args &&...args) && {
350  return std::move(append(std::forward<Args>(args)...));
351  }
352 
353  /// Attaches a note to this diagnostic.
354  Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt) {
355  assert(isActive() && "diagnostic not active");
356  return impl->attachNote(noteLoc);
357  }
358 
359  /// Returns the underlying diagnostic or nullptr if this diagnostic isn't
360  /// active.
361  Diagnostic *getUnderlyingDiagnostic() { return impl ? &*impl : nullptr; }
362 
363  /// Reports the diagnostic to the engine.
364  void report();
365 
366  /// Abandons this diagnostic so that it will no longer be reported.
367  void abandon();
368 
369  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
370  /// 'success' if this is an empty diagnostic.
371  operator LogicalResult() const;
372 
373  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
374  /// 'success' if this is an empty diagnostic.
375  operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
376 
377  /// Allow an inflight diagnostic to be converted to FailureOr<T>. Always
378  /// results in 'failure' because this cast cannot possibly return an object of
379  /// 'T'.
380  template <typename T>
381  operator FailureOr<T>() const {
382  return failure();
383  }
384 
385 private:
386  InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
387  InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
389  : owner(owner), impl(std::move(rhs)) {}
390 
391  /// Returns true if the diagnostic is still active, i.e. it has a live
392  /// diagnostic.
393  bool isActive() const { return impl.has_value(); }
394 
395  /// Returns true if the diagnostic is still in flight to be reported.
396  bool isInFlight() const { return owner; }
397 
398  // Allow access to the constructor.
399  friend DiagnosticEngine;
400 
401  /// The engine that this diagnostic is to report to.
402  DiagnosticEngine *owner = nullptr;
403 
404  /// The raw diagnostic that is inflight to be reported.
405  std::optional<Diagnostic> impl;
406 };
407 
408 //===----------------------------------------------------------------------===//
409 // DiagnosticEngine
410 //===----------------------------------------------------------------------===//
411 
412 /// This class is the main interface for diagnostics. The DiagnosticEngine
413 /// manages the registration of diagnostic handlers as well as the core API for
414 /// diagnostic emission. This class should not be constructed directly, but
415 /// instead interfaced with via an MLIRContext instance.
417 public:
419 
420  // Diagnostic handler registration and use. MLIR supports the ability for the
421  // IR to carry arbitrary metadata about operation location information. If a
422  // problem is detected by the compiler, it can invoke the emitError /
423  // emitWarning / emitRemark method on an Operation and have it get reported
424  // through this interface.
425  //
426  // Tools using MLIR are encouraged to register error handlers and define a
427  // schema for their location information. If they don't, then warnings and
428  // notes will be dropped and errors will be emitted to errs.
429 
430  /// The handler type for MLIR diagnostics. This function takes a diagnostic as
431  /// input, and returns success if the handler has fully processed this
432  /// diagnostic. Returns failure otherwise.
433  using HandlerTy = llvm::unique_function<LogicalResult(Diagnostic &)>;
434 
435  /// A handle to a specific registered handler object.
436  using HandlerID = uint64_t;
437 
438  /// Register a new handler for diagnostics to the engine. Diagnostics are
439  /// process by handlers in stack-like order, meaning that the last added
440  /// handlers will process diagnostics first. This function returns a unique
441  /// identifier for the registered handler, which can be used to unregister
442  /// this handler at a later time.
444 
445  /// Set the diagnostic handler with a function that returns void. This is a
446  /// convenient wrapper for handlers that always completely process the given
447  /// diagnostic.
448  template <typename FuncTy, typename RetT = decltype(std::declval<FuncTy>()(
449  std::declval<Diagnostic &>()))>
450  std::enable_if_t<std::is_same<RetT, void>::value, HandlerID>
451  registerHandler(FuncTy &&handler) {
452  return registerHandler([=](Diagnostic &diag) {
453  handler(diag);
454  return success();
455  });
456  }
457 
458  /// Erase the registered diagnostic handler with the given identifier.
459  void eraseHandler(HandlerID id);
460 
461  /// Create a new inflight diagnostic with the given location and severity.
463  assert(severity != DiagnosticSeverity::Note &&
464  "notes should not be emitted directly");
465  return InFlightDiagnostic(this, Diagnostic(loc, severity));
466  }
467 
468  /// Emit a diagnostic using the registered issue handler if present, or with
469  /// the default behavior if not. The diagnostic instance is consumed in the
470  /// process.
471  void emit(Diagnostic &&diag);
472 
473 private:
474  friend class MLIRContextImpl;
476 
477  /// The internal implementation of the DiagnosticEngine.
478  std::unique_ptr<detail::DiagnosticEngineImpl> impl;
479 };
480 
481 /// Utility method to emit an error message using this location.
483 InFlightDiagnostic emitError(Location loc, const Twine &message);
484 
485 /// Utility method to emit a warning message using this location.
487 InFlightDiagnostic emitWarning(Location loc, const Twine &message);
488 
489 /// Utility method to emit a remark message using this location.
491 InFlightDiagnostic emitRemark(Location loc, const Twine &message);
492 
493 /// Overloads of the above emission functions that take an optionally null
494 /// location. If the location is null, no diagnostic is emitted and a failure is
495 /// returned. Given that the provided location may be null, these methods take
496 /// the diagnostic arguments directly instead of relying on the returned
497 /// InFlightDiagnostic.
498 template <typename... Args>
499 LogicalResult emitOptionalError(std::optional<Location> loc, Args &&...args) {
500  if (loc)
501  return emitError(*loc).append(std::forward<Args>(args)...);
502  return failure();
503 }
504 template <typename... Args>
505 LogicalResult emitOptionalWarning(std::optional<Location> loc, Args &&...args) {
506  if (loc)
507  return emitWarning(*loc).append(std::forward<Args>(args)...);
508  return failure();
509 }
510 template <typename... Args>
511 LogicalResult emitOptionalRemark(std::optional<Location> loc, Args &&...args) {
512  if (loc)
513  return emitRemark(*loc).append(std::forward<Args>(args)...);
514  return failure();
515 }
516 
517 //===----------------------------------------------------------------------===//
518 // ScopedDiagnosticHandler
519 //===----------------------------------------------------------------------===//
520 
521 /// This diagnostic handler is a simple RAII class that registers and erases a
522 /// diagnostic handler on a given context. This class can be either be used
523 /// directly, or in conjunction with a derived diagnostic handler.
525 public:
526  explicit ScopedDiagnosticHandler(MLIRContext *ctx) : handlerID(0), ctx(ctx) {}
527  template <typename FuncTy>
528  ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
529  : handlerID(0), ctx(ctx) {
530  setHandler(std::forward<FuncTy>(handler));
531  }
533 
534 protected:
535  /// Set the handler to manage via RAII.
536  template <typename FuncTy>
537  void setHandler(FuncTy &&handler) {
538  auto &diagEngine = ctx->getDiagEngine();
539  if (handlerID)
540  diagEngine.eraseHandler(handlerID);
541  handlerID = diagEngine.registerHandler(std::forward<FuncTy>(handler));
542  }
543 
544 private:
545  /// The unique id for the scoped handler.
546  DiagnosticEngine::HandlerID handlerID;
547 
548  /// The context to erase the handler from.
549  MLIRContext *ctx;
550 };
551 
552 //===----------------------------------------------------------------------===//
553 // SourceMgrDiagnosticHandler
554 //===----------------------------------------------------------------------===//
555 
556 namespace detail {
557 struct SourceMgrDiagnosticHandlerImpl;
558 } // namespace detail
559 
560 /// This class is a utility diagnostic handler for use with llvm::SourceMgr.
562 public:
563  /// This type represents a functor used to filter out locations when printing
564  /// a diagnostic. It should return true if the provided location is okay to
565  /// display, false otherwise. If all locations in a diagnostic are filtered
566  /// out, the first location is used as the sole location. When deciding
567  /// whether or not to filter a location, this function should not recurse into
568  /// any nested location. This recursion is handled automatically by the
569  /// caller.
570  using ShouldShowLocFn = llvm::unique_function<bool(Location)>;
571 
572  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
573  raw_ostream &os,
575  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
578 
579  /// Emit the given diagnostic information with the held source manager.
580  void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
581  bool displaySourceLine = true);
582 
583  /// Set the maximum depth that a call stack will be printed. Defaults to 10.
584  void setCallStackLimit(unsigned limit);
585 
586 protected:
587  /// Emit the given diagnostic with the held source manager.
589 
590  /// Get a memory buffer for the given file, or nullptr if no file is
591  /// available.
592  const llvm::MemoryBuffer *getBufferForFile(StringRef filename);
593 
594  /// The source manager that we are wrapping.
595  llvm::SourceMgr &mgr;
596 
597  /// The output stream to use when printing diagnostics.
598  raw_ostream &os;
599 
600  /// A functor used when determining if a location for a diagnostic should be
601  /// shown. If null, all locations should be shown.
603 
604 private:
605  /// Convert a location into the given memory buffer into an SMLoc.
606  SMLoc convertLocToSMLoc(FileLineColLoc loc);
607 
608  /// Given a location, returns the first nested location (including 'loc') that
609  /// can be shown to the user.
610  std::optional<Location> findLocToShow(Location loc);
611 
612  /// The maximum depth that a call stack will be printed.
613  unsigned callStackLimit = 10;
614 
615  std::unique_ptr<detail::SourceMgrDiagnosticHandlerImpl> impl;
616 };
617 
618 //===----------------------------------------------------------------------===//
619 // SourceMgrDiagnosticVerifierHandler
620 //===----------------------------------------------------------------------===//
621 
622 namespace detail {
623 struct SourceMgrDiagnosticVerifierHandlerImpl;
624 } // namespace detail
625 
626 /// This class is a utility diagnostic handler for use with llvm::SourceMgr that
627 /// verifies that emitted diagnostics match 'expected-*' lines on the
628 /// corresponding line of the source file.
630 public:
631  enum class Level { None = 0, All, OnlyExpected };
632  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
633  raw_ostream &out,
634  Level level = Level::All);
635  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
636  Level level = Level::All);
638 
639  /// Returns the status of the handler and verifies that all expected
640  /// diagnostics were emitted. This return success if all diagnostics were
641  /// verified correctly, failure otherwise.
642  LogicalResult verify();
643 
644  /// Register this handler with the given context. This is intended for use
645  /// with the splitAndProcessBuffer function.
646  void registerInContext(MLIRContext *ctx);
647 
648 private:
649  /// Process a single diagnostic.
650  void process(Diagnostic &diag);
651 
652  /// Process a LocationAttr diagnostic.
653  void process(LocationAttr loc, StringRef msg, DiagnosticSeverity kind);
654 
655  std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
656 };
657 
658 //===----------------------------------------------------------------------===//
659 // ParallelDiagnosticHandler
660 //===----------------------------------------------------------------------===//
661 
662 namespace detail {
663 struct ParallelDiagnosticHandlerImpl;
664 } // namespace detail
665 
666 /// This class is a utility diagnostic handler for use when multi-threading some
667 /// part of the compiler where diagnostics may be emitted. This handler ensures
668 /// a deterministic ordering to the emitted diagnostics that mirrors that of a
669 /// single-threaded compilation.
671 public:
674 
675  /// Set the order id for the current thread. This is required to be set by
676  /// each thread that will be emitting diagnostics to this handler. The orderID
677  /// corresponds to the order in which diagnostics would be emitted when
678  /// executing synchronously. For example, if we were processing a list
679  /// of operations [a, b, c] on a single-thread. Diagnostics emitted while
680  /// processing operation 'a' would be emitted before those for 'b' or 'c'.
681  /// This corresponds 1-1 with the 'orderID'. The thread that is processing 'a'
682  /// should set the orderID to '0'; the thread processing 'b' should set it to
683  /// '1'; and so on and so forth. This provides a way for the handler to
684  /// deterministically order the diagnostics that it receives given the thread
685  /// that it is receiving on.
686  void setOrderIDForThread(size_t orderID);
687 
688  /// Remove the order id for the current thread. This removes the thread from
689  /// diagnostics tracking.
690  void eraseOrderIDForThread();
691 
692 private:
693  std::unique_ptr<detail::ParallelDiagnosticHandlerImpl> impl;
694 };
695 } // namespace mlir
696 
697 #endif
union mlir::linalg::@1257::ArityGroupAndKind::Kind kind
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:416
uint64_t HandlerID
A handle to a specific registered handler object.
Definition: Diagnostics.h:436
InFlightDiagnostic emit(Location loc, DiagnosticSeverity severity)
Create a new inflight diagnostic with the given location and severity.
Definition: Diagnostics.h:462
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:451
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:433
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
SmallVectorImpl< DiagnosticArgument > & getMetadata()
Returns the current list of diagnostic metadata.
Definition: Diagnostics.h:278
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:257
Diagnostic & operator<<(Operation *op)
Definition: Diagnostics.h:204
Diagnostic & append(Arg1 &&arg1, Arg2 &&arg2, Args &&...args)
Append arguments to the diagnostic.
Definition: Diagnostics.h:230
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:222
Diagnostic & operator=(Diagnostic &&)=default
llvm::pointee_iterator< NoteVector::iterator > note_iterator
Definition: Diagnostics.h:252
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:215
llvm::pointee_iterator< NoteVector::const_iterator > const_note_iterator
Definition: Diagnostics.h:254
Diagnostic & append(Arg &&arg)
Append one argument to the diagnostic.
Definition: Diagnostics.h:236
Diagnostic & operator<<(const char(&val)[n])
Stream in a string literal.
Definition: Diagnostics.h:188
iterator_range< const_note_iterator > getNotes() const
Definition: Diagnostics.h:260
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(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.
An instance of this location represents a tuple of file, line number, and column number.
Definition: Location.h:174
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:316
InFlightDiagnostic && operator<<(Arg &&arg) &&
Definition: Diagnostics.h:336
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
Definition: Diagnostics.h:354
InFlightDiagnostic & operator<<(Arg &&arg) &
Stream operator for new diagnostic arguments.
Definition: Diagnostics.h:332
InFlightDiagnostic & append(Args &&...args) &
Append arguments to the diagnostic.
Definition: Diagnostics.h:342
InFlightDiagnostic && append(Args &&...args) &&
Definition: Diagnostics.h:349
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:361
InFlightDiagnostic(InFlightDiagnostic &&rhs)
Definition: Diagnostics.h:319
void abandon()
Abandons this diagnostic so that it will no longer be reported.
Location objects represent source locations information in MLIR.
Definition: Location.h:32
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:76
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:63
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.
A wrapper class that allows for printing an operation with a set of flags, useful to act as a "stream...
Definition: Operation.h:1111
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:670
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:524
ScopedDiagnosticHandler(MLIRContext *ctx)
Definition: Diagnostics.h:526
ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
Definition: Diagnostics.h:528
void setHandler(FuncTy &&handler)
Set the handler to manage via RAII.
Definition: Diagnostics.h:537
This class is a utility diagnostic handler for use with llvm::SourceMgr.
Definition: Diagnostics.h:561
void setCallStackLimit(unsigned limit)
Set the maximum depth that a call stack will be printed. Defaults to 10.
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:598
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:602
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:595
llvm::unique_function< bool(Location)> ShouldShowLocFn
This type represents a functor used to filter out locations when printing a diagnostic.
Definition: Diagnostics.h:570
This class is a utility diagnostic handler for use with llvm::SourceMgr that verifies that emitted di...
Definition: Diagnostics.h:629
SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out, Level level=Level::All)
void registerInContext(MLIRContext *ctx)
Register this handler with the given context.
LogicalResult verify()
Returns the status of the handler and verifies that all expected diagnostics were emitted.
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
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:41
LogicalResult emitOptionalRemark(std::optional< Location > loc, Args &&...args)
Definition: Diagnostics.h:511
LogicalResult emitOptionalError(std::optional< Location > loc, Args &&...args)
Overloads of the above emission functions that take an optionally null location.
Definition: Diagnostics.h:499
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:505
@ String
A string value.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78