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