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 /// Returns a string argument that refers to a copy of `val` owned by this
303 /// diagnostic, so the argument remains valid for as long as the diagnostic
304 /// does. This is useful for adding a non-constant string to the metadata.
305 DiagnosticArgument getStringArgument(const Twine &val);
306
307 /// Starts a new message part. This has no effect if the current message part
308 /// is empty.
309 void startNewMessagePart();
310
311private:
312 Diagnostic(const Diagnostic &rhs) = delete;
313 Diagnostic &operator=(const Diagnostic &rhs) = delete;
314
315 /// The source location.
316 Location loc;
317
318 /// The severity of this diagnostic.
319 DiagnosticSeverity severity;
320
321 /// The current list of arguments.
323
324 /// A list of string values used as arguments. This is used to guarantee the
325 /// liveness of non-constant strings used in diagnostics.
327
328 /// The exclusive end indices in `arguments` of completed message parts.
329 /// Most diagnostics have only one part, so avoid reserving inline storage.
330 SmallVector<size_t, 0> messagePartEnds;
331
332 /// A list of attached notes.
333 NoteVector notes;
334
335 /// A list of metadata attached to this Diagnostic.
337};
338
340 diag.print(os);
341 return os;
342}
343
344//===----------------------------------------------------------------------===//
345// InFlightDiagnostic
346//===----------------------------------------------------------------------===//
347
348namespace diag {
349/// Starts a new message part in an in-flight diagnostic. Leading, trailing, and
350/// consecutive uses of `next` do not create empty message parts.
352} // namespace diag
353
354/// This class represents a diagnostic that is inflight and set to be reported.
355/// This allows for last minute modifications of the diagnostic before it is
356/// emitted by a DiagnosticEngine.
358public:
361 : owner(rhs.owner), impl(std::move(rhs.impl)) {
362 // Reset the rhs diagnostic.
363 rhs.impl.reset();
364 rhs.abandon();
365 }
367 if (isInFlight())
368 report();
369 }
370
371 /// Stream operator for new diagnostic arguments.
372 template <typename Arg>
374 return append(std::forward<Arg>(arg));
375 }
376 template <typename Arg>
378 return std::move(append(std::forward<Arg>(arg)));
379 }
380
381 /// Enables stream-style manipulators to be chained into the diagnostic.
384 return manip(*this);
385 }
386
389 return std::move(manip(*this));
390 }
391
392 /// Append arguments to the diagnostic.
393 template <typename... Args>
394 InFlightDiagnostic &append(Args &&...args) & {
395 assert(isActive() && "diagnostic not active");
396 if (isInFlight())
397 impl->append(std::forward<Args>(args)...);
398 return *this;
399 }
400 template <typename... Args>
401 InFlightDiagnostic &&append(Args &&...args) && {
402 return std::move(append(std::forward<Args>(args)...));
403 }
404
405 /// Attaches a note to this diagnostic.
406 Diagnostic &attachNote(std::optional<Location> noteLoc = std::nullopt) {
407 assert(isActive() && "diagnostic not active");
408 return impl->attachNote(noteLoc);
409 }
410
411 /// Returns the underlying diagnostic or nullptr if this diagnostic isn't
412 /// active.
413 Diagnostic *getUnderlyingDiagnostic() { return impl ? &*impl : nullptr; }
414
415 /// Reports the diagnostic to the engine.
416 void report();
417
418 /// Abandons this diagnostic so that it will no longer be reported.
419 void abandon();
420
421 /// Allow an inflight diagnostic to be converted to 'failure', otherwise
422 /// 'success' if this is an empty diagnostic.
423 operator LogicalResult() const;
424
425 /// Allow an inflight diagnostic to be converted to 'failure', otherwise
426 /// 'success' if this is an empty diagnostic.
427 operator ParseResult() const { return ParseResult(LogicalResult(*this)); }
428
429 /// Allow an inflight diagnostic to be converted to FailureOr<T>. Always
430 /// results in 'failure' because this cast cannot possibly return an object of
431 /// 'T'.
432 template <typename T>
433 operator FailureOr<T>() const {
434 return failure();
435 }
436
437private:
438 InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
439 InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
441 : owner(owner), impl(std::move(rhs)) {}
442
443 /// Returns true if the diagnostic is still active, i.e. it has a live
444 /// diagnostic.
445 bool isActive() const { return impl.has_value(); }
446
447 /// Returns true if the diagnostic is still in flight to be reported.
448 bool isInFlight() const { return owner; }
449
450 // Allow access to the constructor.
451 friend DiagnosticEngine;
453
454 /// The engine that this diagnostic is to report to.
455 DiagnosticEngine *owner = nullptr;
456
457 /// The raw diagnostic that is inflight to be reported.
458 std::optional<Diagnostic> impl;
459};
460
462 diag.impl->startNewMessagePart();
463 return diag;
464}
465
466//===----------------------------------------------------------------------===//
467// DiagnosticEngine
468//===----------------------------------------------------------------------===//
469
470/// This class is the main interface for diagnostics. The DiagnosticEngine
471/// manages the registration of diagnostic handlers as well as the core API for
472/// diagnostic emission. This class should not be constructed directly, but
473/// instead interfaced with via an MLIRContext instance.
474class DiagnosticEngine {
475public:
477
478 // Diagnostic handler registration and use. MLIR supports the ability for the
479 // IR to carry arbitrary metadata about operation location information. If a
480 // problem is detected by the compiler, it can invoke the emitError /
481 // emitWarning / emitRemark method on an Operation and have it get reported
482 // through this interface.
483 //
484 // Tools using MLIR are encouraged to register error handlers and define a
485 // schema for their location information. If they don't, then warnings and
486 // notes will be dropped and errors will be emitted to errs.
487
488 /// The handler type for MLIR diagnostics. This function takes a diagnostic as
489 /// input, and returns success if the handler has fully processed this
490 /// diagnostic. Returns failure otherwise.
491 using HandlerTy = llvm::unique_function<LogicalResult(Diagnostic &)>;
492
493 /// A handle to a specific registered handler object.
494 using HandlerID = uint64_t;
495
496 /// Register a new handler for diagnostics to the engine. Diagnostics are
497 /// process by handlers in stack-like order, meaning that the last added
498 /// handlers will process diagnostics first. This function returns a unique
499 /// identifier for the registered handler, which can be used to unregister
500 /// this handler at a later time.
502
503 /// Set the diagnostic handler with a function that returns void. This is a
504 /// convenient wrapper for handlers that always completely process the given
505 /// diagnostic.
506 template <typename FuncTy, typename RetT = decltype(std::declval<FuncTy>()(
507 std::declval<Diagnostic &>()))>
508 std::enable_if_t<std::is_same<RetT, void>::value, HandlerID>
509 registerHandler(FuncTy &&handler) {
510 return registerHandler([=](Diagnostic &diag) {
511 handler(diag);
512 return success();
513 });
514 }
515
516 /// Erase the registered diagnostic handler with the given identifier.
517 void eraseHandler(HandlerID id);
518
519 /// Create a new inflight diagnostic with the given location and severity.
521 assert(severity != DiagnosticSeverity::Note &&
522 "notes should not be emitted directly");
523 return InFlightDiagnostic(this, Diagnostic(loc, severity));
524 }
525
526 /// Emit a diagnostic using the registered issue handler if present, or with
527 /// the default behavior if not. The diagnostic instance is consumed in the
528 /// process.
529 void emit(Diagnostic &&diag);
530
531private:
532 friend class MLIRContextImpl;
533 DiagnosticEngine();
534
535 /// The internal implementation of the DiagnosticEngine.
536 std::unique_ptr<detail::DiagnosticEngineImpl> impl;
537};
538
539/// Utility method to emit an error message using this location.
541InFlightDiagnostic emitError(Location loc, const Twine &message);
542
543/// Utility method to emit a warning message using this location.
545InFlightDiagnostic emitWarning(Location loc, const Twine &message);
546
547/// Utility method to emit a remark message using this location.
549InFlightDiagnostic emitRemark(Location loc, const Twine &message);
550
551/// Overloads of the above emission functions that take an optionally null
552/// location. If the location is null, no diagnostic is emitted and a failure is
553/// returned. Given that the provided location may be null, these methods take
554/// the diagnostic arguments directly instead of relying on the returned
555/// InFlightDiagnostic.
556template <typename... Args>
557LogicalResult emitOptionalError(std::optional<Location> loc, Args &&...args) {
558 if (loc)
559 return emitError(*loc).append(std::forward<Args>(args)...);
560 return failure();
561}
562template <typename... Args>
563LogicalResult emitOptionalWarning(std::optional<Location> loc, Args &&...args) {
564 if (loc)
565 return emitWarning(*loc).append(std::forward<Args>(args)...);
566 return failure();
567}
568template <typename... Args>
569LogicalResult emitOptionalRemark(std::optional<Location> loc, Args &&...args) {
570 if (loc)
571 return emitRemark(*loc).append(std::forward<Args>(args)...);
572 return failure();
573}
574
575//===----------------------------------------------------------------------===//
576// ScopedDiagnosticHandler
577//===----------------------------------------------------------------------===//
578
579/// This diagnostic handler is a simple RAII class that registers and erases a
580/// diagnostic handler on a given context. This class can be either be used
581/// directly, or in conjunction with a derived diagnostic handler.
583public:
584 explicit ScopedDiagnosticHandler(MLIRContext *ctx) : handlerID(0), ctx(ctx) {}
585 template <typename FuncTy>
586 ScopedDiagnosticHandler(MLIRContext *ctx, FuncTy &&handler)
587 : handlerID(0), ctx(ctx) {
588 setHandler(std::forward<FuncTy>(handler));
589 }
591
592protected:
593 /// Set the handler to manage via RAII.
594 template <typename FuncTy>
595 void setHandler(FuncTy &&handler) {
596 auto &diagEngine = ctx->getDiagEngine();
597 if (handlerID)
598 diagEngine.eraseHandler(handlerID);
599 handlerID = diagEngine.registerHandler(std::forward<FuncTy>(handler));
600 }
601
602private:
603 /// The unique id for the scoped handler.
605
606 /// The context to erase the handler from.
607 MLIRContext *ctx;
608};
609
610//===----------------------------------------------------------------------===//
611// SourceMgrDiagnosticHandler
612//===----------------------------------------------------------------------===//
613
614namespace detail {
615struct SourceMgrDiagnosticHandlerImpl;
616} // namespace detail
617
618/// This class is a utility diagnostic handler for use with llvm::SourceMgr.
620public:
621 /// This type represents a functor used to filter out locations when printing
622 /// a diagnostic. It should return true if the provided location is okay to
623 /// display, false otherwise. If all locations in a diagnostic are filtered
624 /// out, the first location is used as the sole location. When deciding
625 /// whether or not to filter a location, this function should not recurse into
626 /// any nested location. This recursion is handled automatically by the
627 /// caller.
628 using ShouldShowLocFn = llvm::unique_function<bool(Location)>;
629
630 SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
633 SourceMgrDiagnosticHandler(llvm::SourceMgr &mgr, MLIRContext *ctx,
636
637 /// Emit the given diagnostic information with the held source manager.
638 void emitDiagnostic(Location loc, Twine message, DiagnosticSeverity kind,
639 bool displaySourceLine = true);
640
641 /// Set the maximum depth that a call stack will be printed. Defaults to 10.
642 void setCallStackLimit(unsigned limit);
643
644protected:
645 /// Emit the given diagnostic with the held source manager.
647
648 /// Get a memory buffer for the given file, or nullptr if no file is
649 /// available.
650 const llvm::MemoryBuffer *getBufferForFile(StringRef filename);
651
652 /// The source manager that we are wrapping.
653 llvm::SourceMgr &mgr;
654
655 /// The output stream to use when printing diagnostics.
657
658 /// A functor used when determining if a location for a diagnostic should be
659 /// shown. If null, all locations should be shown.
661
662private:
663 /// Convert a location into the given memory buffer into an SMLoc.
664 SMLoc convertLocToSMLoc(FileLineColLoc loc);
665
666 /// Given a location, returns the first nested location (including 'loc') that
667 /// can be shown to the user.
668 std::optional<Location> findLocToShow(Location loc);
669
670 /// The maximum depth that a call stack will be printed.
671 unsigned callStackLimit = 10;
672
673 std::unique_ptr<detail::SourceMgrDiagnosticHandlerImpl> impl;
674};
675
676//===----------------------------------------------------------------------===//
677// SourceMgrDiagnosticVerifierHandler
678//===----------------------------------------------------------------------===//
679
680namespace detail {
681struct SourceMgrDiagnosticVerifierHandlerImpl;
682} // namespace detail
683
684/// This class is a utility diagnostic handler for use with llvm::SourceMgr that
685/// verifies that emitted diagnostics match 'expected-*' lines on the
686/// corresponding line of the source file.
688public:
689 enum class Level { None = 0, All, OnlyExpected };
690 SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
691 raw_ostream &out,
692 Level level = Level::All);
693 SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
694 Level level = Level::All);
696
697 /// Returns the status of the handler and verifies that all expected
698 /// diagnostics were emitted. This return success if all diagnostics were
699 /// verified correctly, failure otherwise.
700 LogicalResult verify();
701
702 /// Register this handler with `ctx` and return a scoped registration.
703 /// Destroy the returned handle before either this handler or `ctx`.
704 [[nodiscard]] std::unique_ptr<ScopedDiagnosticHandler>
706
707private:
708 /// Process a diagnostic and its notes.
709 void process(Diagnostic &diag);
710
711 /// Process a LocationAttr diagnostic.
712 void process(LocationAttr loc, StringRef msg, DiagnosticSeverity kind);
713
714 std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
715};
716
717//===----------------------------------------------------------------------===//
718// ParallelDiagnosticHandler
719//===----------------------------------------------------------------------===//
720
721namespace detail {
722struct ParallelDiagnosticHandlerImpl;
723} // namespace detail
724
725/// This class is a utility diagnostic handler for use when multi-threading some
726/// part of the compiler where diagnostics may be emitted. This handler ensures
727/// a deterministic ordering to the emitted diagnostics that mirrors that of a
728/// single-threaded compilation.
730public:
733
734 /// Set the order id for the current thread. This is required to be set by
735 /// each thread that will be emitting diagnostics to this handler. The orderID
736 /// corresponds to the order in which diagnostics would be emitted when
737 /// executing synchronously. For example, if we were processing a list
738 /// of operations [a, b, c] on a single-thread. Diagnostics emitted while
739 /// processing operation 'a' would be emitted before those for 'b' or 'c'.
740 /// This corresponds 1-1 with the 'orderID'. The thread that is processing 'a'
741 /// should set the orderID to '0'; the thread processing 'b' should set it to
742 /// '1'; and so on and so forth. This provides a way for the handler to
743 /// deterministically order the diagnostics that it receives given the thread
744 /// that it is receiving on.
745 ///
746 /// Each set must be paired with an erase on the same thread before the
747 /// handler is destroyed. Nesting distinct handlers on one thread is
748 /// supported; reentrant use of one handler on one thread is not.
749 void setOrderIDForThread(size_t orderID);
750
751 /// Remove the order id for the current thread. This removes the thread from
752 /// diagnostics tracking. Must be called on the same thread that set it,
753 /// before the handler is destroyed.
755
756private:
757 std::unique_ptr<detail::ParallelDiagnosticHandlerImpl> impl;
758};
759} // namespace mlir
760
761#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
DiagnosticArgument getStringArgument(const Twine &val)
Returns a string argument that refers to a copy of val owned by this diagnostic, so the argument rema...
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:176
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:71
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:1171
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:229
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)