MLIR 24.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.
156///
157/// A diagnostic may contain multiple message parts that share its location,
158/// severity, metadata, and attached notes. Empty message parts are ignored.
160 using NoteVector = SmallVector<std::unique_ptr<Diagnostic>, 0>;
161
162public:
164 : loc(loc), severity(severity) {}
165 Diagnostic(Diagnostic &&) = default;
167
168 /// Returns the severity of this diagnostic.
169 DiagnosticSeverity getSeverity() const { return severity; }
170
171 /// Returns the source location for this diagnostic.
172 Location getLocation() const { return loc; }
173
174 /// Returns the current list of diagnostic arguments.
176 ArrayRef<DiagnosticArgument> getArguments() const { return arguments; }
177
178 /// Stream operator for inserting new diagnostic arguments.
179 template <typename Arg>
180 std::enable_if_t<!std::is_convertible<Arg, StringRef>::value &&
181 std::is_constructible<DiagnosticArgument, Arg>::value,
182 Diagnostic &>
183 operator<<(Arg &&val) {
184 arguments.push_back(DiagnosticArgument(std::forward<Arg>(val)));
185 return *this;
186 }
187 Diagnostic &operator<<(StringAttr val);
188
189 /// Stream in a string literal.
190 template <size_t n>
191 Diagnostic &operator<<(const char (&val)[n]) {
192 arguments.push_back(DiagnosticArgument(val));
193 return *this;
194 }
195
196 /// Stream in a Twine argument.
197 Diagnostic &operator<<(char val);
198 Diagnostic &operator<<(const Twine &val);
199 Diagnostic &operator<<(Twine &&val);
200
201 /// Stream in an OperationName.
203
204 /// Stream in an Operation.
207 Diagnostic &operator<<(Operation *op) { return *this << *op; }
208 /// Append an operation with the given printing flags.
209 Diagnostic &appendOp(Operation &op, const OpPrintingFlags &flags);
210
211 /// Stream in a Value.
213
214 /// Stream in an enum that has a `stringifyEnum` function.
215 template <typename EnumT>
216 std::enable_if_t<
217 std::is_enum_v<EnumT> &&
218 std::is_convertible_v<decltype(stringifyEnum(std::declval<EnumT>())),
219 StringRef>,
220 Diagnostic &>
221 operator<<(EnumT val) {
222 return *this << stringifyEnum(val);
223 }
224
225 /// Stream in a range.
226 template <typename T, typename ValueT = llvm::detail::ValueOfRange<T>>
227 std::enable_if_t<!std::is_constructible<DiagnosticArgument, T>::value,
228 Diagnostic &>
229 operator<<(T &&range) {
230 return appendRange(range);
231 }
232
233 /// Append a range to the diagnostic. The default delimiter between elements
234 /// is ','.
235 template <typename T>
236 Diagnostic &appendRange(const T &c, const char *delim = ", ") {
237 llvm::interleave(
238 c, [this](const auto &a) { *this << a; }, [&]() { *this << delim; });
239 return *this;
240 }
241
242 /// Append arguments to the diagnostic.
243 template <typename Arg1, typename Arg2, typename... Args>
244 Diagnostic &append(Arg1 &&arg1, Arg2 &&arg2, Args &&...args) {
245 append(std::forward<Arg1>(arg1));
246 return append(std::forward<Arg2>(arg2), std::forward<Args>(args)...);
247 }
248 /// Append one argument to the diagnostic.
249 template <typename Arg>
250 Diagnostic &append(Arg &&arg) {
251 *this << std::forward<Arg>(arg);
252 return *this;
253 }
254
255 /// Outputs this diagnostic to a stream. If `messagePartIndex` is provided,
256 /// only that message part is printed; otherwise, all arguments are printed
257 /// without separators between message parts.
258 void print(raw_ostream &os,
259 std::optional<int64_t> messagePartIndex = std::nullopt) const;
260
261 /// Converts the diagnostic to a string, concatenating all the parts if there
262 /// are multiples.
263 std::string str() const;
264
265 /// Converts each message part to a separate string. Returns a single string
266 /// if the diagnostic has not been divided into multiple parts.
268
269 /// Attaches a note to this diagnostic. A new location may be optionally
270 /// provided, if not, then the location defaults to the one specified for this
271 /// diagnostic. Notes may not be attached to other notes.
272 Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt);
273
274 using note_iterator = llvm::pointee_iterator<NoteVector::iterator>;
276 llvm::pointee_iterator<NoteVector::const_iterator>;
277
278 /// Returns the notes held by this diagnostic.
280 return llvm::make_pointee_range(notes);
281 }
283 return llvm::make_pointee_range(notes);
284 }
285
286 /// Allow a diagnostic to be converted to 'failure'.
287 operator LogicalResult() const;
288
289 /// Allow a diagnostic to be converted to 'failure'.
290 operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
291
292 /// Allow a diagnostic to be converted to FailureOr<T>. Always results in
293 /// 'failure' because this cast cannot possibly return an object of 'T'.
294 template <typename T>
295 operator FailureOr<T>() const {
296 return failure();
297 }
298
299 /// Returns the current list of diagnostic metadata.
301
302 /// Starts a new message part. This has no effect if the current message part
303 /// is empty.
304 void startNewMessagePart();
305
306private:
307 Diagnostic(const Diagnostic &rhs) = delete;
308 Diagnostic &operator=(const Diagnostic &rhs) = delete;
309
310 /// The source location.
311 Location loc;
312
313 /// The severity of this diagnostic.
314 DiagnosticSeverity severity;
315
316 /// The current list of arguments.
318
319 /// A list of string values used as arguments. This is used to guarantee the
320 /// liveness of non-constant strings used in diagnostics.
322
323 /// The exclusive end indices in `arguments` of completed message parts.
324 /// Most diagnostics have only one part, so avoid reserving inline storage.
325 SmallVector<size_t, 0> messagePartEnds;
326
327 /// A list of attached notes.
328 NoteVector notes;
329
330 /// A list of metadata attached to this Diagnostic.
332};
333
335 diag.print(os);
336 return os;
337}
338
339//===----------------------------------------------------------------------===//
340// InFlightDiagnostic
341//===----------------------------------------------------------------------===//
342
343namespace diag {
344/// Starts a new message part in an in-flight diagnostic. Leading, trailing, and
345/// consecutive uses of `next` do not create empty message parts.
347} // namespace diag
348
349/// This class represents a diagnostic that is inflight and set to be reported.
350/// This allows for last minute modifications of the diagnostic before it is
351/// emitted by a DiagnosticEngine.
353public:
356 : owner(rhs.owner), impl(std::move(rhs.impl)) {
357 // Reset the rhs diagnostic.
358 rhs.impl.reset();
359 rhs.abandon();
360 }
362 if (isInFlight())
363 report();
364 }
365
366 /// Stream operator for new diagnostic arguments.
367 template <typename Arg>
369 return append(std::forward<Arg>(arg));
370 }
371 template <typename Arg>
373 return std::move(append(std::forward<Arg>(arg)));
374 }
375
376 /// Enables stream-style manipulators to be chained into the diagnostic.
379 return manip(*this);
380 }
381
384 return std::move(manip(*this));
385 }
386
387 /// Append arguments to the diagnostic.
388 template <typename... Args>
389 InFlightDiagnostic &append(Args &&...args) & {
390 assert(isActive() && "diagnostic not active");
391 if (isInFlight())
392 impl->append(std::forward<Args>(args)...);
393 return *this;
394 }
395 template <typename... Args>
396 InFlightDiagnostic &&append(Args &&...args) && {
397 return std::move(append(std::forward<Args>(args)...));
398 }
399
400 /// Attaches a note to this diagnostic.
401 Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt) {
402 assert(isActive() && "diagnostic not active");
403 return impl->attachNote(noteLoc);
404 }
405
406 /// Returns the underlying diagnostic or nullptr if this diagnostic isn't
407 /// active.
408 Diagnostic *getUnderlyingDiagnostic() { return impl ? &*impl : nullptr; }
409
410 /// Reports the diagnostic to the engine.
411 void report();
412
413 /// Abandons this diagnostic so that it will no longer be reported.
414 void abandon();
415
416 /// Allow an inflight diagnostic to be converted to 'failure', otherwise
417 /// 'success' if this is an empty diagnostic.
418 operator LogicalResult() const;
419
420 /// Allow an inflight diagnostic to be converted to 'failure', otherwise
421 /// 'success' if this is an empty diagnostic.
422 operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
423
424 /// Allow an inflight diagnostic to be converted to FailureOr<T>. Always
425 /// results in 'failure' because this cast cannot possibly return an object of
426 /// 'T'.
427 template <typename T>
428 operator FailureOr<T>() const {
429 return failure();
430 }
431
432private:
433 InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
434 InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
436 : owner(owner), impl(std::move(rhs)) {}
437
438 /// Returns true if the diagnostic is still active, i.e. it has a live
439 /// diagnostic.
440 bool isActive() const { return impl.has_value(); }
441
442 /// Returns true if the diagnostic is still in flight to be reported.
443 bool isInFlight() const { return owner; }
444
445 // Allow access to the constructor.
446 friend DiagnosticEngine;
448
449 /// The engine that this diagnostic is to report to.
450 DiagnosticEngine *owner = nullptr;
451
452 /// The raw diagnostic that is inflight to be reported.
453 std::optional<Diagnostic> impl;
454};
455
457 diag.impl->startNewMessagePart();
458 return diag;
459}
460
461//===----------------------------------------------------------------------===//
462// DiagnosticEngine
463//===----------------------------------------------------------------------===//
464
465/// This class is the main interface for diagnostics. The DiagnosticEngine
466/// manages the registration of diagnostic handlers as well as the core API for
467/// diagnostic emission. This class should not be constructed directly, but
468/// instead interfaced with via an MLIRContext instance.
469class DiagnosticEngine {
470public:
472
473 // Diagnostic handler registration and use. MLIR supports the ability for the
474 // IR to carry arbitrary metadata about operation location information. If a
475 // problem is detected by the compiler, it can invoke the emitError /
476 // emitWarning / emitRemark method on an Operation and have it get reported
477 // through this interface.
478 //
479 // Tools using MLIR are encouraged to register error handlers and define a
480 // schema for their location information. If they don't, then warnings and
481 // notes will be dropped and errors will be emitted to errs.
482
483 /// The handler type for MLIR diagnostics. This function takes a diagnostic as
484 /// input, and returns success if the handler has fully processed this
485 /// diagnostic. Returns failure otherwise.
486 using HandlerTy = llvm::unique_function<LogicalResult(Diagnostic &)>;
487
488 /// A handle to a specific registered handler object.
489 using HandlerID = uint64_t;
490
491 /// Register a new handler for diagnostics to the engine. Diagnostics are
492 /// process by handlers in stack-like order, meaning that the last added
493 /// handlers will process diagnostics first. This function returns a unique
494 /// identifier for the registered handler, which can be used to unregister
495 /// this handler at a later time.
497
498 /// Set the diagnostic handler with a function that returns void. This is a
499 /// convenient wrapper for handlers that always completely process the given
500 /// diagnostic.
501 template <typename FuncTy, typename RetT = decltype(std::declval<FuncTy>()(
502 std::declval<Diagnostic &>()))>
503 std::enable_if_t<std::is_same<RetT, void>::value, HandlerID>
504 registerHandler(FuncTy &&handler) {
505 return registerHandler([=](Diagnostic &diag) {
506 handler(diag);
507 return success();
508 });
509 }
510
511 /// Erase the registered diagnostic handler with the given identifier.
512 void eraseHandler(HandlerID id);
513
514 /// Create a new inflight diagnostic with the given location and severity.
516 assert(severity != DiagnosticSeverity::Note &&
517 "notes should not be emitted directly");
518 return InFlightDiagnostic(this, Diagnostic(loc, severity));
519 }
520
521 /// Emit a diagnostic using the registered issue handler if present, or with
522 /// the default behavior if not. The diagnostic instance is consumed in the
523 /// process.
524 void emit(Diagnostic &&diag);
525
526private:
527 friend class MLIRContextImpl;
528 DiagnosticEngine();
529
530 /// The internal implementation of the DiagnosticEngine.
531 std::unique_ptr<detail::DiagnosticEngineImpl> impl;
532};
533
534/// Utility method to emit an error message using this location.
536InFlightDiagnostic emitError(Location loc, const Twine &message);
537
538/// Utility method to emit a warning message using this location.
540InFlightDiagnostic emitWarning(Location loc, const Twine &message);
541
542/// Utility method to emit a remark message using this location.
544InFlightDiagnostic emitRemark(Location loc, const Twine &message);
545
546/// Overloads of the above emission functions that take an optionally null
547/// location. If the location is null, no diagnostic is emitted and a failure is
548/// returned. Given that the provided location may be null, these methods take
549/// the diagnostic arguments directly instead of relying on the returned
550/// InFlightDiagnostic.
551template <typename... Args>
552LogicalResult emitOptionalError(std::optional<Location> loc, Args &&...args) {
553 if (loc)
554 return emitError(*loc).append(std::forward<Args>(args)...);
555 return failure();
556}
557template <typename... Args>
558LogicalResult emitOptionalWarning(std::optional<Location> loc, Args &&...args) {
559 if (loc)
560 return emitWarning(*loc).append(std::forward<Args>(args)...);
561 return failure();
562}
563template <typename... Args>
564LogicalResult emitOptionalRemark(std::optional<Location> loc, Args &&...args) {
565 if (loc)
566 return emitRemark(*loc).append(std::forward<Args>(args)...);
567 return failure();
568}
569
570//===----------------------------------------------------------------------===//
571// ScopedDiagnosticHandler
572//===----------------------------------------------------------------------===//
573
574/// This diagnostic handler is a simple RAII class that registers and erases a
575/// diagnostic handler on a given context. This class can be either be used
576/// directly, or in conjunction with a derived diagnostic handler.
578public:
579 explicit ScopedDiagnosticHandler(MLIRContext *ctx) : handlerID(0), ctx(ctx) {}
580 template <typename FuncTy>
581 ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
582 : handlerID(0), ctx(ctx) {
583 setHandler(std::forward<FuncTy>(handler));
584 }
586
587protected:
588 /// Set the handler to manage via RAII.
589 template <typename FuncTy>
590 void setHandler(FuncTy &&handler) {
591 auto &diagEngine = ctx->getDiagEngine();
592 if (handlerID)
593 diagEngine.eraseHandler(handlerID);
594 handlerID = diagEngine.registerHandler(std::forward<FuncTy>(handler));
595 }
596
597private:
598 /// The unique id for the scoped handler.
600
601 /// The context to erase the handler from.
602 MLIRContext *ctx;
603};
604
605//===----------------------------------------------------------------------===//
606// SourceMgrDiagnosticHandler
607//===----------------------------------------------------------------------===//
608
609namespace detail {
610struct SourceMgrDiagnosticHandlerImpl;
611} // namespace detail
612
613/// This class is a utility diagnostic handler for use with llvm::SourceMgr.
615public:
616 /// This type represents a functor used to filter out locations when printing
617 /// a diagnostic. It should return true if the provided location is okay to
618 /// display, false otherwise. If all locations in a diagnostic are filtered
619 /// out, the first location is used as the sole location. When deciding
620 /// whether or not to filter a location, this function should not recurse into
621 /// any nested location. This recursion is handled automatically by the
622 /// caller.
623 using ShouldShowLocFn = llvm::unique_function<bool(Location)>;
624
625 SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
628 SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
631
632 /// Emit the given diagnostic information with the held source manager.
633 void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
634 bool displaySourceLine = true);
635
636 /// Set the maximum depth that a call stack will be printed. Defaults to 10.
637 void setCallStackLimit(unsigned limit);
638
639protected:
640 /// Emit the given diagnostic with the held source manager.
642
643 /// Get a memory buffer for the given file, or nullptr if no file is
644 /// available.
645 const llvm::MemoryBuffer *getBufferForFile(StringRef filename);
646
647 /// The source manager that we are wrapping.
648 llvm::SourceMgr &mgr;
649
650 /// The output stream to use when printing diagnostics.
652
653 /// A functor used when determining if a location for a diagnostic should be
654 /// shown. If null, all locations should be shown.
656
657private:
658 /// Convert a location into the given memory buffer into an SMLoc.
659 SMLoc convertLocToSMLoc(FileLineColLoc loc);
660
661 /// Given a location, returns the first nested location (including 'loc') that
662 /// can be shown to the user.
663 std::optional<Location> findLocToShow(Location loc);
664
665 /// The maximum depth that a call stack will be printed.
666 unsigned callStackLimit = 10;
667
668 std::unique_ptr<detail::SourceMgrDiagnosticHandlerImpl> impl;
669};
670
671//===----------------------------------------------------------------------===//
672// SourceMgrDiagnosticVerifierHandler
673//===----------------------------------------------------------------------===//
674
675namespace detail {
676struct SourceMgrDiagnosticVerifierHandlerImpl;
677} // namespace detail
678
679/// This class is a utility diagnostic handler for use with llvm::SourceMgr that
680/// verifies that emitted diagnostics match 'expected-*' lines on the
681/// corresponding line of the source file.
683public:
684 enum class Level { None = 0, All, OnlyExpected };
685 SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
686 raw_ostream &out,
687 Level level = Level::All);
688 SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
689 Level level = Level::All);
691
692 /// Returns the status of the handler and verifies that all expected
693 /// diagnostics were emitted. This return success if all diagnostics were
694 /// verified correctly, failure otherwise.
695 LogicalResult verify();
696
697 /// Register this handler with `ctx` and return a scoped registration.
698 /// Destroy the returned handle before either this handler or `ctx`.
699 [[nodiscard]] std::unique_ptr<ScopedDiagnosticHandler>
701
702private:
703 /// Process a diagnostic and its notes.
704 void process(Diagnostic &diag);
705
706 /// Process a LocationAttr diagnostic.
707 void process(LocationAttr loc, StringRef msg, DiagnosticSeverity kind);
708
709 std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
710};
711
712//===----------------------------------------------------------------------===//
713// ParallelDiagnosticHandler
714//===----------------------------------------------------------------------===//
715
716namespace detail {
717struct ParallelDiagnosticHandlerImpl;
718} // namespace detail
719
720/// This class is a utility diagnostic handler for use when multi-threading some
721/// part of the compiler where diagnostics may be emitted. This handler ensures
722/// a deterministic ordering to the emitted diagnostics that mirrors that of a
723/// single-threaded compilation.
725public:
728
729 /// Set the order id for the current thread. This is required to be set by
730 /// each thread that will be emitting diagnostics to this handler. The orderID
731 /// corresponds to the order in which diagnostics would be emitted when
732 /// executing synchronously. For example, if we were processing a list
733 /// of operations [a, b, c] on a single-thread. Diagnostics emitted while
734 /// processing operation 'a' would be emitted before those for 'b' or 'c'.
735 /// This corresponds 1-1 with the 'orderID'. The thread that is processing 'a'
736 /// should set the orderID to '0'; the thread processing 'b' should set it to
737 /// '1'; and so on and so forth. This provides a way for the handler to
738 /// deterministically order the diagnostics that it receives given the thread
739 /// that it is receiving on.
740 ///
741 /// Each set must be paired with an erase on the same thread before the
742 /// handler is destroyed. Nesting distinct handlers on one thread is
743 /// supported; reentrant use of one handler on one thread is not.
744 void setOrderIDForThread(size_t orderID);
745
746 /// Remove the order id for the current thread. This removes the thread from
747 /// diagnostics tracking. Must be called on the same thread that set it,
748 /// before the handler is destroyed.
750
751private:
752 std::unique_ptr<detail::ParallelDiagnosticHandlerImpl> impl;
753};
754} // namespace mlir
755
756#endif
return success()
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, concatenating all the parts if there are multiples.
Diagnostic & operator<<(const char(&val)[n])
Stream in a string literal.
void startNewMessagePart()
Starts a new message part.
Diagnostic & append(Arg &&arg)
Append one argument to the diagnostic.
Diagnostic & operator<<(Operation *op)
Location getLocation() const
Returns the source location for this diagnostic.
SmallVector< std::string > strs() const
Converts each message part to a separate string.
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.
void print(raw_ostream &os, std::optional< int64_t > messagePartIndex=std::nullopt) const
Outputs this diagnostic to a stream.
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
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:64
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:1169
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
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)
std::unique_ptr< ScopedDiagnosticHandler > registerInContext(MLIRContext *ctx)
Register this handler with ctx and return a scoped registration.
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:227
AttrTypeReplacer.
InFlightDiagnostic & next(InFlightDiagnostic &diag)
Starts a new message part in an in-flight diagnostic.
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)