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