#ifndef MLIR_IR_DIAGNOSTICS_H
#define MLIR_IR_DIAGNOSTICS_H
+#include "mlir/IR/Location.h"
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
#include <functional>
namespace mlir {
-class Location;
+class DiagnosticEngine;
+class LogicalResult;
+class Type;
namespace detail {
struct DiagnosticEngineImpl;
};
//===----------------------------------------------------------------------===//
+// DiagnosticArgument
+//===----------------------------------------------------------------------===//
+
+/// A variant type that holds a single argument for a diagnostic.
+class DiagnosticArgument {
+public:
+ /// Enum that represents the different kinds of diagnostic arguments
+ /// supported.
+ enum class DiagnosticArgumentKind {
+ Integer,
+ String,
+ Type,
+ Unsigned,
+ };
+
+ /// Outputs this argument to a stream.
+ void print(raw_ostream &os) const;
+
+ /// Returns the kind of this argument.
+ DiagnosticArgumentKind getKind() const { return kind; }
+
+ /// Returns this argument as a string.
+ StringRef getAsString() const {
+ assert(getKind() == DiagnosticArgumentKind::String);
+ return stringVal;
+ }
+
+ /// Returns this argument as a signed integer.
+ int64_t getAsInteger() const {
+ assert(getKind() == DiagnosticArgumentKind::Integer);
+ return static_cast<int64_t>(opaqueVal);
+ }
+
+ /// Returns this argument as a Type.
+ Type getAsType() const;
+
+ /// Returns this argument as an unsigned integer.
+ uint64_t getAsUnsigned() const {
+ assert(getKind() == DiagnosticArgumentKind::Unsigned);
+ return static_cast<uint64_t>(opaqueVal);
+ }
+
+private:
+ friend class Diagnostic;
+
+ // Construct from an int64_t.
+ explicit DiagnosticArgument(int64_t val)
+ : kind(DiagnosticArgumentKind::Integer), opaqueVal(val) {}
+
+ // Construct from an uint64_t.
+ explicit DiagnosticArgument(uint64_t val)
+ : kind(DiagnosticArgumentKind::Unsigned), opaqueVal(val) {}
+
+ // Construct from a string reference.
+ explicit DiagnosticArgument(StringRef val)
+ : kind(DiagnosticArgumentKind::String), stringVal(val) {}
+
+ // Construct from a Type.
+ explicit DiagnosticArgument(Type val);
+
+ /// The kind of this argument.
+ DiagnosticArgumentKind kind;
+
+ /// The value of this argument.
+ union {
+ intptr_t opaqueVal;
+ StringRef stringVal;
+ };
+};
+
+inline raw_ostream &operator<<(raw_ostream &os, const DiagnosticArgument &arg) {
+ arg.print(os);
+ return os;
+}
+
+//===----------------------------------------------------------------------===//
+// Diagnostic
+//===----------------------------------------------------------------------===//
+
+/// This class contains all of the information necessary to report a diagnostic
+/// to the DiagnosticEngine. It should generally not be constructed directly,
+/// and instead used transitively via InFlightDiagnostic.
+class Diagnostic {
+public:
+ Diagnostic(Location loc, DiagnosticSeverity severity)
+ : loc(loc), severity(severity) {}
+ Diagnostic(Diagnostic &&) = default;
+ Diagnostic &operator=(Diagnostic &&) = default;
+
+ /// Returns the severity of this diagnostic.
+ DiagnosticSeverity getSeverity() const { return severity; }
+
+ /// Returns the source location for this diagnostic.
+ Location getLocation() const { return loc; }
+
+ /// Returns the current list of diagnostic arguments.
+ MutableArrayRef<DiagnosticArgument> getArguments() { return arguments; }
+ ArrayRef<DiagnosticArgument> getArguments() const { return arguments; }
+
+ /// Stream operator for inserting new diagnostic arguments.
+ template <typename Arg>
+ typename std::enable_if<!std::is_convertible<Arg, StringRef>::value,
+ Diagnostic &>::type
+ operator<<(Arg &&val) {
+ arguments.push_back(DiagnosticArgument(std::forward<Arg>(val)));
+ return *this;
+ }
+ Diagnostic &operator<<(const char *val) {
+ arguments.push_back(DiagnosticArgument(val));
+ return *this;
+ }
+ Diagnostic &operator<<(const Twine &val) {
+ llvm::SmallString<0> str;
+ arguments.push_back(DiagnosticArgument(val.toStringRef(str)));
+ stringArguments.emplace_back(std::move(str), arguments.size());
+ return *this;
+ }
+
+ /// Outputs this diagnostic to a stream.
+ void print(raw_ostream &os) const;
+
+ /// Converts the diagnostic to a string.
+ std::string str() const;
+
+private:
+ Diagnostic(const Diagnostic &rhs) = delete;
+ Diagnostic &operator=(const Diagnostic &rhs) = delete;
+
+ /// The source location.
+ Location loc;
+
+ /// The severity of this diagnostic.
+ DiagnosticSeverity severity;
+
+ /// The current list of arguments.
+ SmallVector<DiagnosticArgument, 4> arguments;
+
+ /// A list of string values used as arguments and the corresponding index of
+ /// those arguments. This is used to guarantee the liveness of non-constant
+ /// strings used in diagnostics.
+ std::vector<std::pair<llvm::SmallString<0>, unsigned>> stringArguments;
+};
+
+inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) {
+ diag.print(os);
+ return os;
+}
+
+//===----------------------------------------------------------------------===//
+// InFlightDiagnostic
+//===----------------------------------------------------------------------===//
+
+/// This class represents a diagnostic that is inflight and set to be reported.
+/// This allows for last minute modifications of the diagnostic before it is
+/// emitted by a DiagnosticEngine.
+class InFlightDiagnostic {
+public:
+ InFlightDiagnostic() = default;
+ InFlightDiagnostic(InFlightDiagnostic &&rhs)
+ : owner(rhs.owner), impl(std::move(rhs.impl)) {
+ // Reset the rhs diagnostic.
+ rhs.impl.reset();
+ }
+ ~InFlightDiagnostic() {
+ if (isInFlight())
+ report();
+ }
+
+ /// Stream operator for new diagnostic arguments.
+ template <typename Arg> InFlightDiagnostic &&operator<<(Arg &&arg) && {
+ appendArgument(std::forward<Arg>(arg));
+ return std::move(*this);
+ }
+ template <typename Arg> InFlightDiagnostic &operator<<(Arg &&arg) & {
+ appendArgument(std::forward<Arg>(arg));
+ return *this;
+ }
+
+ /// Reports the diagnostic to the engine.
+ void report();
+
+ /// Allow an inflight diagnostic to be converted to 'failure', otherwise
+ /// 'success' if this is an empty diagnostic.
+ operator LogicalResult() const;
+
+ /// Returns if the diagnostic is still in flight.
+ bool isInFlight() const { return impl.hasValue(); }
+
+private:
+ InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
+ InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;
+ InFlightDiagnostic(DiagnosticEngine *owner, Diagnostic &&rhs)
+ : owner(owner), impl(std::move(rhs)) {}
+
+ /// Add an argument to the internal diagnostic.
+ template <typename Arg> void appendArgument(Arg &&arg) {
+ assert(isInFlight() && "diagnostic not inflight");
+ *impl << std::forward<Arg>(arg);
+ }
+
+ // Allow access to the constructor.
+ friend DiagnosticEngine;
+
+ /// The engine that this diagnostic is to report to.
+ DiagnosticEngine *owner;
+
+ /// The raw diagnostic that is inflight to be reported.
+ llvm::Optional<Diagnostic> impl;
+};
+
+//===----------------------------------------------------------------------===//
// DiagnosticEngine
//===----------------------------------------------------------------------===//
//
// Tools using MLIR are encouraged to register error handlers and define a
// schema for their location information. If they don't, then warnings and
- // notes will be dropped and errors will terminate the process with exit(1).
+ // notes will be dropped and errors will be emitted to errs.
using HandlerTy =
std::function<void(Location, StringRef, DiagnosticSeverity)>;
/// Return the current diagnostic handler, or null if none is present.
HandlerTy getHandler();
+ /// Create a new inflight diagnostic with the given location and severity.
+ InFlightDiagnostic emit(Location loc, DiagnosticSeverity severity) {
+ return InFlightDiagnostic(this, Diagnostic(loc, severity));
+ }
+
/// Emit a diagnostic using the registered issue handle if present, or with
- /// the default behavior if not. The MLIR compiler should not generally
- /// interact with this, it should use methods on Operation instead.
- void emit(Location loc, const Twine &msg, DiagnosticSeverity severity);
+ /// the default behavior if not.
+ void emit(const Diagnostic &diag);
private:
friend class MLIRContextImpl;
void dump();
/// Emit an error about fatal conditions with this function, reporting up to
- /// any diagnostic handlers that may be listening. This function always
- /// returns failure. NOTE: This may terminate the containing application,
- /// only use when the IR is in an inconsistent state.
- LogicalResult emitError(const Twine &message);
+ /// any diagnostic handlers that may be listening.
+ InFlightDiagnostic emitError(const Twine &message);
/// Emit a warning about this function, reporting up to any diagnostic
/// handlers that may be listening.
- void emitWarning(const Twine &message);
+ InFlightDiagnostic emitWarning(const Twine &message);
/// Emit a remark about this function, reporting up to any diagnostic
/// handlers that may be listening.
- void emitRemark(const Twine &message);
+ InFlightDiagnostic emitRemark(const Twine &message);
/// Displays the CFG in a window. This is for use from the debugger and
/// depends on Graphviz to generate the graph.
class AbstractOperation;
class DiagnosticEngine;
class Dialect;
+class InFlightDiagnostic;
class Location;
class MLIRContextImpl;
class StorageUniquer;
// MLIRContextImpl type.
MLIRContextImpl &getImpl() { return *impl.get(); }
- /// Emit an error message using the diagnostic engine and return true.
- bool emitError(Location location, const Twine &message);
+ /// Emit an error message using the diagnostic engine.
+ InFlightDiagnostic emitError(Location location, const Twine &message);
/// Emit a remark message using the diagnostic engine.
- void emitRemark(Location location, const Twine &message);
+ InFlightDiagnostic emitRemark(Location location, const Twine &message);
/// Returns the diagnostic engine for this context.
DiagnosticEngine &getDiagEngine();
void erase() { state->erase(); }
/// Emit an error about fatal conditions with this operation, reporting up to
- /// any diagnostic handlers that may be listening. This function always
- /// returns failure. NOTE: This may terminate the containing application,
- /// only use when the IR is in an inconsistent state.
- LogicalResult emitError(const Twine &message);
+ /// any diagnostic handlers that may be listening.
+ InFlightDiagnostic emitError(const Twine &message);
/// Emit an error with the op name prefixed, like "'dim' op " which is
/// convenient for verifiers. This always returns failure.
- LogicalResult emitOpError(const Twine &message);
+ InFlightDiagnostic emitOpError(const Twine &message);
/// Emit a warning about this operation, reporting up to any diagnostic
/// handlers that may be listening.
- void emitWarning(const Twine &message);
+ InFlightDiagnostic emitWarning(const Twine &message);
/// Emit a note about this operation, reporting up to any diagnostic
/// handlers that may be listening.
- void emitNote(const Twine &message);
+ InFlightDiagnostic emitNote(const Twine &message);
/// Emit a remark about this operation, reporting up to any diagnostic
/// handlers that may be listening.
- void emitRemark(const Twine &message);
+ InFlightDiagnostic emitRemark(const Twine &message);
// These are default implementations of customization hooks.
public:
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Block.h"
+#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/OperationSupport.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist.h"
//===--------------------------------------------------------------------===//
/// Emit an error with the op name prefixed, like "'dim' op " which is
- /// convenient for verifiers. This function always returns failure.
- LogicalResult emitOpError(const Twine &message);
+ /// convenient for verifiers.
+ InFlightDiagnostic emitOpError(const Twine &message);
/// Emit an error about fatal conditions with this operation, reporting up to
- /// any diagnostic handlers that may be listening. This function always
- /// returns failure. NOTE: This may terminate the containing application,
- /// only use when the IR is in an inconsistent state.
- LogicalResult emitError(const Twine &message);
+ /// any diagnostic handlers that may be listening.
+ InFlightDiagnostic emitError(const Twine &message);
/// Emit a warning about this operation, reporting up to any diagnostic
/// handlers that may be listening.
- void emitWarning(const Twine &message);
+ InFlightDiagnostic emitWarning(const Twine &message);
/// Emit a note about this operation, reporting up to any diagnostic
/// handlers that may be listening.
- void emitNote(const Twine &message);
+ InFlightDiagnostic emitNote(const Twine &message);
/// Emit a remark about this operation, reporting up to any diagnostic
/// handlers that may be listening.
- void emitRemark(const Twine &message);
+ InFlightDiagnostic emitRemark(const Twine &message);
private:
Operation(Location location, OperationName name, unsigned numResults,
// Pre-conditions.
if (!elementType.isSigned()) {
// TODO: Support unsigned storage type.
- return rewriter.getContext()->getDiagEngine().emit(
- loc, "unimplemented: dequantize signed uniform",
- DiagnosticSeverity::Warning),
- nullptr;
+ rewriter.getContext()->getDiagEngine().emit(loc,
+ DiagnosticSeverity::Warning)
+ << "unimplemented: dequantize signed uniform";
+ return nullptr;
}
Type storageType = elementType.castToStorageType(input->getType());
UniformQuantizedPerAxisType elementType,
PatternRewriter &rewriter) {
// TODO: Support per-axis dequantize.
- return rewriter.getContext()->getDiagEngine().emit(
- loc, "unimplemented: per-axis uniform dequantization",
- DiagnosticSeverity::Warning),
- nullptr;
+ rewriter.getContext()->getDiagEngine().emit(loc, DiagnosticSeverity::Warning)
+ << "unimplemented: per-axis uniform dequantization";
+ return nullptr;
}
static Value *emitDequantize(Location loc, Value *input,
#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"
+#include "mlir/IR/Types.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
using namespace mlir;
using namespace mlir::detail;
+//===----------------------------------------------------------------------===//
+// DiagnosticArgument
+//===----------------------------------------------------------------------===//
+
+// Construct from a Type.
+DiagnosticArgument::DiagnosticArgument(Type val)
+ : kind(DiagnosticArgumentKind::Type),
+ opaqueVal(reinterpret_cast<intptr_t>(val.getAsOpaquePointer())) {}
+
+/// Returns this argument as a Type.
+Type DiagnosticArgument::getAsType() const {
+ assert(getKind() == DiagnosticArgumentKind::Type);
+ return Type::getFromOpaquePointer(reinterpret_cast<const void *>(opaqueVal));
+}
+
+/// Outputs this argument to a stream.
+void DiagnosticArgument::print(raw_ostream &os) const {
+ switch (kind) {
+ case DiagnosticArgumentKind::Integer:
+ os << getAsInteger();
+ break;
+ case DiagnosticArgumentKind::String:
+ os << getAsString();
+ break;
+ case DiagnosticArgumentKind::Type:
+ os << getAsType();
+ break;
+ case DiagnosticArgumentKind::Unsigned:
+ os << getAsUnsigned();
+ break;
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Diagnostic
+//===----------------------------------------------------------------------===//
+
+/// Outputs this diagnostic to a stream.
+void Diagnostic::print(raw_ostream &os) const {
+ for (auto &arg : getArguments())
+ arg.print(os);
+}
+
+/// Convert the diagnostic to a string.
+std::string Diagnostic::str() const {
+ std::string str;
+ llvm::raw_string_ostream os(str);
+ print(os);
+ return os.str();
+}
+
+//===----------------------------------------------------------------------===//
+// InFlightDiagnostic
+//===----------------------------------------------------------------------===//
+
+/// Allow an inflight diagnostic to be converted to 'failure', otherwise
+/// 'success' if this is an empty diagnostic.
+InFlightDiagnostic::operator LogicalResult() const {
+ return failure(isInFlight());
+}
+
+/// Reports the diagnostic to the engine.
+void InFlightDiagnostic::report() {
+ if (isInFlight()) {
+ owner->emit(*impl);
+ impl.reset();
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// DiagnosticEngineImpl
+//===----------------------------------------------------------------------===//
+
namespace mlir {
namespace detail {
struct DiagnosticEngineImpl {
+ /// Emit a diagnostic using the registered issue handle if present, or with
+ /// the default behavior if not.
+ void emit(Location loc, StringRef msg, DiagnosticSeverity severity);
+
/// A mutex to ensure that diagnostics emission is thread-safe.
llvm::sys::SmartMutex<true> mutex;
} // namespace detail
} // namespace mlir
-//===----------------------------------------------------------------------===//
-// DiagnosticEngine
-//===----------------------------------------------------------------------===//
-
-DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {}
-DiagnosticEngine::~DiagnosticEngine() {}
-
-/// Register a diagnostic handler with this engine. The handler is
-/// passed location information if present (nullptr if not) along with a
-/// message and a severity that indicates whether this is an error, warning,
-/// etc.
-void DiagnosticEngine::setHandler(const HandlerTy &handler) {
- llvm::sys::SmartScopedLock<true> lock(impl->mutex);
- impl->handler = handler;
-}
-
-/// Return the current diagnostic handler, or null if none is present.
-auto DiagnosticEngine::getHandler() -> HandlerTy {
- llvm::sys::SmartScopedLock<true> lock(impl->mutex);
- return impl->handler;
-}
-
/// Emit a diagnostic using the registered issue handle if present, or with
-/// the default behavior if not. The MLIR compiler should not generally
-/// interact with this, it should use methods on Operation instead.
-void DiagnosticEngine::emit(Location loc, const Twine &msg,
- DiagnosticSeverity severity) {
- /// Lock access to the diagnostic engine.
- llvm::sys::SmartScopedLock<true> lock(impl->mutex);
+/// the default behavior if not.
+void DiagnosticEngineImpl::emit(Location loc, StringRef msg,
+ DiagnosticSeverity severity) {
+ // Lock access to the handler.
+ llvm::sys::SmartScopedLock<true> lock(mutex);
// If we had a handler registered, emit the diagnostic using it.
- if (impl->handler) {
+ if (handler) {
// TODO(b/131756158) FusedLoc should be handled by the diagnostic handler
// instead of here.
- // Check to see if we are emitting a diagnostic on a fused
- // location.
+ // Check to see if we are emitting a diagnostic on a fused location.
if (auto fusedLoc = loc.dyn_cast<FusedLoc>()) {
auto fusedLocs = fusedLoc->getLocations();
return;
}
- return impl->handler(loc, msg.str(), severity);
+ return handler(loc, msg, severity);
}
// Otherwise, if this is an error we emit it to stderr.
os << msg << '\n';
os.flush();
}
+
+//===----------------------------------------------------------------------===//
+// DiagnosticEngine
+//===----------------------------------------------------------------------===//
+
+DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {}
+DiagnosticEngine::~DiagnosticEngine() {}
+
+/// Set the diagnostic handler for this engine. The handler is passed
+/// location information if present (nullptr if not) along with a message and
+/// a severity that indicates whether this is an error, warning, etc. Note
+/// that this replaces any existing handler.
+void DiagnosticEngine::setHandler(const HandlerTy &handler) {
+ llvm::sys::SmartScopedLock<true> lock(impl->mutex);
+ impl->handler = handler;
+}
+
+/// Return the current diagnostic handler, or null if none is present.
+auto DiagnosticEngine::getHandler() -> HandlerTy {
+ llvm::sys::SmartScopedLock<true> lock(impl->mutex);
+ return impl->handler;
+}
+
+/// Emit a diagnostic using the registered issue handler if present, or with
+/// the default behavior if not.
+void DiagnosticEngine::emit(const Diagnostic &diag) {
+ impl->emit(diag.getLocation(), diag.str(), diag.getSeverity());
+}
// =============================================================================
#include "mlir/IR/Dialect.h"
+#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/DialectHooks.h"
#include "mlir/IR/MLIRContext.h"
#include "llvm/ADT/Twine.h"
/// Emit a remark about this function, reporting up to any diagnostic
/// handlers that may be listening.
-void Function::emitRemark(const Twine &message) {
- getContext()->emitRemark(getLoc(), message);
+InFlightDiagnostic Function::emitRemark(const Twine &message) {
+ return getContext()->emitRemark(getLoc(), message);
}
/// Emit a warning about this function, reporting up to any diagnostic
/// handlers that may be listening.
-void Function::emitWarning(const Twine &message) {
- getContext()->getDiagEngine().emit(getLoc(), message,
- DiagnosticSeverity::Warning);
+InFlightDiagnostic Function::emitWarning(const Twine &message) {
+ return getContext()->getDiagEngine().emit(getLoc(),
+ DiagnosticSeverity::Warning)
+ << message;
}
/// Emit an error about fatal conditions with this function, reporting up to
/// any diagnostic handlers that may be listening. This function always
/// returns failure. NOTE: This may terminate the containing application, only
/// use when the IR is in an inconsistent state.
-LogicalResult Function::emitError(const Twine &message) {
- return getContext()->emitError(getLoc(), message), failure();
+InFlightDiagnostic Function::emitError(const Twine &message) {
+ return getContext()->emitError(getLoc(), message);
}
/// Clone the internal blocks from this function into dest and all attributes
// Diagnostic Handlers
//===----------------------------------------------------------------------===//
-bool MLIRContext::emitError(Location location, const llvm::Twine &message) {
- getImpl().diagEngine.emit(location, message, DiagnosticSeverity::Error);
- return true;
+InFlightDiagnostic MLIRContext::emitError(Location location,
+ const llvm::Twine &message) {
+ return getImpl().diagEngine.emit(location, DiagnosticSeverity::Error)
+ << message;
}
/// Emit a remark message using the diagnostic engine.
-void MLIRContext::emitRemark(Location location, const Twine &message) {
- getImpl().diagEngine.emit(location, message, DiagnosticSeverity::Remark);
+InFlightDiagnostic MLIRContext::emitRemark(Location location,
+ const Twine &message) {
+ return getImpl().diagEngine.emit(location, DiagnosticSeverity::Remark)
+ << message;
}
/// Returns the diagnostic engine for this context.
/// Emit a remark about this operation, reporting up to any diagnostic
/// handlers that may be listening.
-void Operation::emitRemark(const Twine &message) {
- getContext()->emitRemark(getLoc(), message);
+InFlightDiagnostic Operation::emitRemark(const Twine &message) {
+ return getContext()->emitRemark(getLoc(), message);
}
/// Emit a note about this operation, reporting up to any diagnostic
/// handlers that may be listening.
-void Operation::emitNote(const Twine &message) {
- getContext()->getDiagEngine().emit(getLoc(), message,
- DiagnosticSeverity::Note);
+InFlightDiagnostic Operation::emitNote(const Twine &message) {
+ return getContext()->getDiagEngine().emit(getLoc(), DiagnosticSeverity::Note)
+ << message;
}
/// Emit a warning about this operation, reporting up to any diagnostic
/// handlers that may be listening.
-void Operation::emitWarning(const Twine &message) {
- getContext()->getDiagEngine().emit(getLoc(), message,
- DiagnosticSeverity::Warning);
+InFlightDiagnostic Operation::emitWarning(const Twine &message) {
+ return getContext()->getDiagEngine().emit(getLoc(),
+ DiagnosticSeverity::Warning)
+ << message;
}
/// Emit an error about fatal conditions with this operation, reporting up to
-/// any diagnostic handlers that may be listening. This function always
-/// returns failure. NOTE: This may terminate the containing application, only
-/// use when the IR is in an inconsistent state.
-LogicalResult Operation::emitError(const Twine &message) {
- return getContext()->emitError(getLoc(), message), failure();
+/// any diagnostic handlers that may be listening.
+InFlightDiagnostic Operation::emitError(const Twine &message) {
+ return getContext()->emitError(getLoc(), message);
}
/// Given an operation 'other' that is within the same parent block, return
/// Emit an error with the op name prefixed, like "'dim' op " which is
/// convenient for verifiers.
-LogicalResult Operation::emitOpError(const Twine &message) {
+InFlightDiagnostic Operation::emitOpError(const Twine &message) {
return emitError(Twine('\'') + getName().getStringRef() + "' op " + message);
}
void OpState::print(OpAsmPrinter *p) { p->printGenericOp(getOperation()); }
/// Emit an error about fatal conditions with this operation, reporting up to
-/// any diagnostic handlers that may be listening. NOTE: This may terminate
-/// the containing application, only use when the IR is in an inconsistent
-/// state.
-LogicalResult OpState::emitError(const Twine &message) {
+/// any diagnostic handlers that may be listening.
+InFlightDiagnostic OpState::emitError(const Twine &message) {
return getOperation()->emitError(message);
}
/// Emit an error with the op name prefixed, like "'dim' op " which is
/// convenient for verifiers.
-LogicalResult OpState::emitOpError(const Twine &message) {
+InFlightDiagnostic OpState::emitOpError(const Twine &message) {
return getOperation()->emitOpError(message);
}
/// Emit a warning about this operation, reporting up to any diagnostic
/// handlers that may be listening.
-void OpState::emitWarning(const Twine &message) {
- getOperation()->emitWarning(message);
+InFlightDiagnostic OpState::emitWarning(const Twine &message) {
+ return getOperation()->emitWarning(message);
}
/// Emit a note about this operation, reporting up to any diagnostic
/// handlers that may be listening.
-void OpState::emitNote(const Twine &message) {
- getOperation()->emitNote(message);
+InFlightDiagnostic OpState::emitNote(const Twine &message) {
+ return getOperation()->emitNote(message);
}
/// Emit a remark about this operation, reporting up to any diagnostic
/// handlers that may be listening.
-void OpState::emitRemark(const Twine &message) {
- getOperation()->emitRemark(message);
+InFlightDiagnostic OpState::emitRemark(const Twine &message) {
+ return getOperation()->emitRemark(message);
}
//===----------------------------------------------------------------------===//
#include "mlir/IR/StandardTypes.h"
#include "TypeDetail.h"
#include "mlir/IR/AffineMap.h"
+#include "mlir/IR/Diagnostics.h"
#include "mlir/Support/STLExtras.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/Twine.h"
#include "mlir/IR/Types.h"
#include "TypeDetail.h"
+#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Dialect.h"
#include "llvm/ADT/Twine.h"
//===----------------------------------------------------------------------===//
#include "Lexer.h"
+#include "mlir/IR/Diagnostics.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/MLIRContext.h"
#include "llvm/Support/SourceMgr.h"
// Emit the diagnostics back to the context.
emitDiagnostics(
[&](Location loc, StringRef message, DiagnosticSeverity kind) {
- return context.getDiagEngine().emit(loc, message, kind);
+ return context.getDiagEngine().emit(loc, kind) << message;
});
}
// NB: Attribute already verified to be boolean, so check if we can indeed
// attach the attribute to this argument, based on its type.
auto argTy = mlirArg->getType().dyn_cast<LLVM::LLVMType>();
- if (!argTy.getUnderlyingType()->isPointerTy())
- return argTy.getContext()->emitError(
+ if (!argTy.getUnderlyingType()->isPointerTy()) {
+ argTy.getContext()->emitError(
func.getLoc(),
"llvm.noalias attribute attached to LLVM non-pointer argument");
+ return true;
+ }
if (attr.getValue())
llvmArg.addAttr(llvm::Attribute::AttrKind::NoAlias);
}