MLIR  19.0.0git
Diagnostics.h
Go to the documentation of this file.
1 //===- Diagnostics.h - MLIR Diagnostics -------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines utilities for emitting diagnostics.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_IR_DIAGNOSTICS_H
14 #define MLIR_IR_DIAGNOSTICS_H
15 
16 #include "mlir/IR/Location.h"
17 #include <functional>
18 #include <optional>
19 
20 namespace llvm {
21 class MemoryBuffer;
22 class SMLoc;
23 class SourceMgr;
24 } // namespace llvm
25 
26 namespace mlir {
27 class DiagnosticEngine;
28 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 private:
275  Diagnostic(const Diagnostic &rhs) = delete;
276  Diagnostic &operator=(const Diagnostic &rhs) = delete;
277 
278  /// The source location.
279  Location loc;
280 
281  /// The severity of this diagnostic.
282  DiagnosticSeverity severity;
283 
284  /// The current list of arguments.
286 
287  /// A list of string values used as arguments. This is used to guarantee the
288  /// liveness of non-constant strings used in diagnostics.
289  std::vector<std::unique_ptr<char[]>> strings;
290 
291  /// A list of attached notes.
292  NoteVector notes;
293 };
294 
295 inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) {
296  diag.print(os);
297  return os;
298 }
299 
300 //===----------------------------------------------------------------------===//
301 // InFlightDiagnostic
302 //===----------------------------------------------------------------------===//
303 
304 /// This class represents a diagnostic that is inflight and set to be reported.
305 /// This allows for last minute modifications of the diagnostic before it is
306 /// emitted by a DiagnosticEngine.
308 public:
309  InFlightDiagnostic() = default;
311  : owner(rhs.owner), impl(std::move(rhs.impl)) {
312  // Reset the rhs diagnostic.
313  rhs.impl.reset();
314  rhs.abandon();
315  }
317  if (isInFlight())
318  report();
319  }
320 
321  /// Stream operator for new diagnostic arguments.
322  template <typename Arg>
324  return append(std::forward<Arg>(arg));
325  }
326  template <typename Arg>
327  InFlightDiagnostic &&operator<<(Arg &&arg) && {
328  return std::move(append(std::forward<Arg>(arg)));
329  }
330 
331  /// Append arguments to the diagnostic.
332  template <typename... Args>
333  InFlightDiagnostic &append(Args &&...args) & {
334  assert(isActive() && "diagnostic not active");
335  if (isInFlight())
336  impl->append(std::forward<Args>(args)...);
337  return *this;
338  }
339  template <typename... Args>
340  InFlightDiagnostic &&append(Args &&...args) && {
341  return std::move(append(std::forward<Args>(args)...));
342  }
343 
344  /// Attaches a note to this diagnostic.
345  Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt) {
346  assert(isActive() && "diagnostic not active");
347  return impl->attachNote(noteLoc);
348  }
349 
350  /// Returns the underlying diagnostic or nullptr if this diagnostic isn't
351  /// active.
352  Diagnostic *getUnderlyingDiagnostic() { return impl ? &*impl : nullptr; }
353 
354  /// Reports the diagnostic to the engine.
355  void report();
356 
357  /// Abandons this diagnostic so that it will no longer be reported.
358  void abandon();
359 
360  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
361  /// 'success' if this is an empty diagnostic.
362  operator LogicalResult() const;
363 
364  /// Allow an inflight diagnostic to be converted to 'failure', otherwise
365  /// 'success' if this is an empty diagnostic.
366  operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
367 
368  /// Allow an inflight diagnostic to be converted to FailureOr<T>. Always
369  /// results in 'failure' because this cast cannot possibly return an object of
370  /// 'T'.
371  template <typename T>
372  operator FailureOr<T>() const {
373  return failure();
374  }
375 
376 private:
377  InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
378  InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
380  : owner(owner), impl(std::move(rhs)) {}
381 
382  /// Returns true if the diagnostic is still active, i.e. it has a live
383  /// diagnostic.
384  bool isActive() const { return impl.has_value(); }
385 
386  /// Returns true if the diagnostic is still in flight to be reported.
387  bool isInFlight() const { return owner; }
388 
389  // Allow access to the constructor.
390  friend DiagnosticEngine;
391 
392  /// The engine that this diagnostic is to report to.
393  DiagnosticEngine *owner = nullptr;
394 
395  /// The raw diagnostic that is inflight to be reported.
396  std::optional<Diagnostic> impl;
397 };
398 
399 //===----------------------------------------------------------------------===//
400 // DiagnosticEngine
401 //===----------------------------------------------------------------------===//
402 
403 /// This class is the main interface for diagnostics. The DiagnosticEngine
404 /// manages the registration of diagnostic handlers as well as the core API for
405 /// diagnostic emission. This class should not be constructed directly, but
406 /// instead interfaced with via an MLIRContext instance.
408 public:
410 
411  // Diagnostic handler registration and use. MLIR supports the ability for the
412  // IR to carry arbitrary metadata about operation location information. If a
413  // problem is detected by the compiler, it can invoke the emitError /
414  // emitWarning / emitRemark method on an Operation and have it get reported
415  // through this interface.
416  //
417  // Tools using MLIR are encouraged to register error handlers and define a
418  // schema for their location information. If they don't, then warnings and
419  // notes will be dropped and errors will be emitted to errs.
420 
421  /// The handler type for MLIR diagnostics. This function takes a diagnostic as
422  /// input, and returns success if the handler has fully processed this
423  /// diagnostic. Returns failure otherwise.
424  using HandlerTy = llvm::unique_function<LogicalResult(Diagnostic &)>;
425 
426  /// A handle to a specific registered handler object.
427  using HandlerID = uint64_t;
428 
429  /// Register a new handler for diagnostics to the engine. Diagnostics are
430  /// process by handlers in stack-like order, meaning that the last added
431  /// handlers will process diagnostics first. This function returns a unique
432  /// identifier for the registered handler, which can be used to unregister
433  /// this handler at a later time.
435 
436  /// Set the diagnostic handler with a function that returns void. This is a
437  /// convenient wrapper for handlers that always completely process the given
438  /// diagnostic.
439  template <typename FuncTy, typename RetT = decltype(std::declval<FuncTy>()(
440  std::declval<Diagnostic &>()))>
441  std::enable_if_t<std::is_same<RetT, void>::value, HandlerID>
442  registerHandler(FuncTy &&handler) {
443  return registerHandler([=](Diagnostic &diag) {
444  handler(diag);
445  return success();
446  });
447  }
448 
449  /// Erase the registered diagnostic handler with the given identifier.
450  void eraseHandler(HandlerID id);
451 
452  /// Create a new inflight diagnostic with the given location and severity.
454  assert(severity != DiagnosticSeverity::Note &&
455  "notes should not be emitted directly");
456  return InFlightDiagnostic(this, Diagnostic(loc, severity));
457  }
458 
459  /// Emit a diagnostic using the registered issue handler if present, or with
460  /// the default behavior if not. The diagnostic instance is consumed in the
461  /// process.
462  void emit(Diagnostic &&diag);
463 
464 private:
465  friend class MLIRContextImpl;
467 
468  /// The internal implementation of the DiagnosticEngine.
469  std::unique_ptr<detail::DiagnosticEngineImpl> impl;
470 };
471 
472 /// Utility method to emit an error message using this location.
474 InFlightDiagnostic emitError(Location loc, const Twine &message);
475 
476 /// Utility method to emit a warning message using this location.
478 InFlightDiagnostic emitWarning(Location loc, const Twine &message);
479 
480 /// Utility method to emit a remark message using this location.
482 InFlightDiagnostic emitRemark(Location loc, const Twine &message);
483 
484 /// Overloads of the above emission functions that take an optionally null
485 /// location. If the location is null, no diagnostic is emitted and a failure is
486 /// returned. Given that the provided location may be null, these methods take
487 /// the diagnostic arguments directly instead of relying on the returned
488 /// InFlightDiagnostic.
489 template <typename... Args>
490 LogicalResult emitOptionalError(std::optional<Location> loc, Args &&...args) {
491  if (loc)
492  return emitError(*loc).append(std::forward<Args>(args)...);
493  return failure();
494 }
495 template <typename... Args>
496 LogicalResult emitOptionalWarning(std::optional<Location> loc, Args &&...args) {
497  if (loc)
498  return emitWarning(*loc).append(std::forward<Args>(args)...);
499  return failure();
500 }
501 template <typename... Args>
502 LogicalResult emitOptionalRemark(std::optional<Location> loc, Args &&...args) {
503  if (loc)
504  return emitRemark(*loc).append(std::forward<Args>(args)...);
505  return failure();
506 }
507 
508 //===----------------------------------------------------------------------===//
509 // ScopedDiagnosticHandler
510 //===----------------------------------------------------------------------===//
511 
512 /// This diagnostic handler is a simple RAII class that registers and erases a
513 /// diagnostic handler on a given context. This class can be either be used
514 /// directly, or in conjunction with a derived diagnostic handler.
516 public:
517  explicit ScopedDiagnosticHandler(MLIRContext *ctx) : handlerID(0), ctx(ctx) {}
518  template <typename FuncTy>
519  ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
520  : handlerID(0), ctx(ctx) {
521  setHandler(std::forward<FuncTy>(handler));
522  }
524 
525 protected:
526  /// Set the handler to manage via RAII.
527  template <typename FuncTy>
528  void setHandler(FuncTy &&handler) {
529  auto &diagEngine = ctx->getDiagEngine();
530  if (handlerID)
531  diagEngine.eraseHandler(handlerID);
532  handlerID = diagEngine.registerHandler(std::forward<FuncTy>(handler));
533  }
534 
535 private:
536  /// The unique id for the scoped handler.
537  DiagnosticEngine::HandlerID handlerID;
538 
539  /// The context to erase the handler from.
540  MLIRContext *ctx;
541 };
542 
543 //===----------------------------------------------------------------------===//
544 // SourceMgrDiagnosticHandler
545 //===----------------------------------------------------------------------===//
546 
547 namespace detail {
548 struct SourceMgrDiagnosticHandlerImpl;
549 } // namespace detail
550 
551 /// This class is a utility diagnostic handler for use with llvm::SourceMgr.
553 public:
554  /// This type represents a functor used to filter out locations when printing
555  /// a diagnostic. It should return true if the provided location is okay to
556  /// display, false otherwise. If all locations in a diagnostic are filtered
557  /// out, the first location is used as the sole location. When deciding
558  /// whether or not to filter a location, this function should not recurse into
559  /// any nested location. This recursion is handled automatically by the
560  /// caller.
561  using ShouldShowLocFn = llvm::unique_function<bool(Location)>;
562 
563  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
564  raw_ostream &os,
566  SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
569 
570  /// Emit the given diagnostic information with the held source manager.
571  void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
572  bool displaySourceLine = true);
573 
574 protected:
575  /// Emit the given diagnostic with the held source manager.
577 
578  /// Get a memory buffer for the given file, or nullptr if no file is
579  /// available.
580  const llvm::MemoryBuffer *getBufferForFile(StringRef filename);
581 
582  /// The source manager that we are wrapping.
583  llvm::SourceMgr &mgr;
584 
585  /// The output stream to use when printing diagnostics.
586  raw_ostream &os;
587 
588  /// A functor used when determining if a location for a diagnostic should be
589  /// shown. If null, all locations should be shown.
591 
592 private:
593  /// Convert a location into the given memory buffer into an SMLoc.
594  SMLoc convertLocToSMLoc(FileLineColLoc loc);
595 
596  /// Given a location, returns the first nested location (including 'loc') that
597  /// can be shown to the user.
598  std::optional<Location> findLocToShow(Location loc);
599 
600  /// The maximum depth that a call stack will be printed.
601  /// TODO: This should be a tunable flag.
602  unsigned callStackLimit = 10;
603 
604  std::unique_ptr<detail::SourceMgrDiagnosticHandlerImpl> impl;
605 };
606 
607 //===----------------------------------------------------------------------===//
608 // SourceMgrDiagnosticVerifierHandler
609 //===----------------------------------------------------------------------===//
610 
611 namespace detail {
612 struct SourceMgrDiagnosticVerifierHandlerImpl;
613 } // namespace detail
614 
615 /// This class is a utility diagnostic handler for use with llvm::SourceMgr that
616 /// verifies that emitted diagnostics match 'expected-*' lines on the
617 /// corresponding line of the source file.
619 public:
620  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
621  raw_ostream &out);
622  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx);
624 
625  /// Returns the status of the handler and verifies that all expected
626  /// diagnostics were emitted. This return success if all diagnostics were
627  /// verified correctly, failure otherwise.
628  LogicalResult verify();
629 
630 private:
631  /// Process a single diagnostic.
632  void process(Diagnostic &diag);
633 
634  /// Process a FileLineColLoc diagnostic.
635  void process(FileLineColLoc loc, StringRef msg, DiagnosticSeverity kind);
636 
637  std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
638 };
639 
640 //===----------------------------------------------------------------------===//
641 // ParallelDiagnosticHandler
642 //===----------------------------------------------------------------------===//
643 
644 namespace detail {
645 struct ParallelDiagnosticHandlerImpl;
646 } // namespace detail
647 
648 /// This class is a utility diagnostic handler for use when multi-threading some
649 /// part of the compiler where diagnostics may be emitted. This handler ensures
650 /// a deterministic ordering to the emitted diagnostics that mirrors that of a
651 /// single-threaded compilation.
653 public:
656 
657  /// Set the order id for the current thread. This is required to be set by
658  /// each thread that will be emitting diagnostics to this handler. The orderID
659  /// corresponds to the order in which diagnostics would be emitted when
660  /// executing synchronously. For example, if we were processing a list
661  /// of operations [a, b, c] on a single-thread. Diagnostics emitted while
662  /// processing operation 'a' would be emitted before those for 'b' or 'c'.
663  /// This corresponds 1-1 with the 'orderID'. The thread that is processing 'a'
664  /// should set the orderID to '0'; the thread processing 'b' should set it to
665  /// '1'; and so on and so forth. This provides a way for the handler to
666  /// deterministically order the diagnostics that it receives given the thread
667  /// that it is receiving on.
668  void setOrderIDForThread(size_t orderID);
669 
670  /// Remove the order id for the current thread. This removes the thread from
671  /// diagnostics tracking.
672  void eraseOrderIDForThread();
673 
674 private:
675  std::unique_ptr<detail::ParallelDiagnosticHandlerImpl> impl;
676 };
677 } // namespace mlir
678 
679 #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:407
uint64_t HandlerID
A handle to a specific registered handler object.
Definition: Diagnostics.h:427
InFlightDiagnostic emit(Location loc, DiagnosticSeverity severity)
Create a new inflight diagnostic with the given location and severity.
Definition: Diagnostics.h:453
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:442
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:424
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
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:307
InFlightDiagnostic && operator<<(Arg &&arg) &&
Definition: Diagnostics.h:327
Diagnostic & attachNote(std::optional< Location > noteLoc=std::nullopt)
Attaches a note to this diagnostic.
Definition: Diagnostics.h:345
InFlightDiagnostic & operator<<(Arg &&arg) &
Stream operator for new diagnostic arguments.
Definition: Diagnostics.h:323
InFlightDiagnostic & append(Args &&...args) &
Append arguments to the diagnostic.
Definition: Diagnostics.h:333
InFlightDiagnostic && append(Args &&...args) &&
Definition: Diagnostics.h:340
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:352
InFlightDiagnostic(InFlightDiagnostic &&rhs)
Definition: Diagnostics.h:310
void abandon()
Abandons this diagnostic so that it will no longer be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
This is the implementation of the MLIRContext class, using the pImpl idiom.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
DiagnosticEngine & getDiagEngine()
Returns the diagnostic engine for this context.
Set of flags used to control the behavior of the various IR print methods (e.g.
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class is a utility diagnostic handler for use when multi-threading some part of the compiler whe...
Definition: Diagnostics.h:652
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:515
ScopedDiagnosticHandler(MLIRContext *ctx)
Definition: Diagnostics.h:517
ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
Definition: Diagnostics.h:519
void setHandler(FuncTy &&handler)
Set the handler to manage via RAII.
Definition: Diagnostics.h:528
This class is a utility diagnostic handler for use with llvm::SourceMgr.
Definition: Diagnostics.h:552
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:586
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:590
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:583
llvm::unique_function< bool(Location)> ShouldShowLocFn
This type represents a functor used to filter out locations when printing a diagnostic.
Definition: Diagnostics.h:561
This class is a utility diagnostic handler for use with llvm::SourceMgr that verifies that emitted di...
Definition: Diagnostics.h:618
LogicalResult verify()
Returns the status of the handler and verifies that all expected diagnostics were emitted.
SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out)
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
Include the generated interface declarations.
Definition: CallGraph.h:229
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
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:502
LogicalResult emitOptionalError(std::optional< Location > loc, Args &&...args)
Overloads of the above emission functions that take an optionally null location.
Definition: Diagnostics.h:490
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:496
@ String
A string value.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78