Optionally emit errors from IntegerType factory functions.
authorAlex Zinenko <zinenko@google.com>
Mon, 12 Nov 2018 23:12:09 +0000 (15:12 -0800)
committerjpienaar <jpienaar@google.com>
Fri, 29 Mar 2019 20:55:50 +0000 (13:55 -0700)
Similarly to other types, introduce "get" and "getChecked" static member
functions for IntegerType.  The latter emits errors to the error handler
registered with the MLIR context and returns a null type for the caller to
handle errors gracefully.  This deduplicates type consistency checks between
the parser and the builder.  Update the parser to call IntegerType::getChecked
for error reporting instead of the builder that would simply assert.

This CL completes the type system error emission refactoring: the parser now
only emits syntax-related errors for types while type factory systems may emit
type consistency errors.

PiperOrigin-RevId: 221165207

mlir/include/mlir/IR/Types.h
mlir/lib/IR/MLIRContext.cpp
mlir/lib/Parser/Parser.cpp

index 1927ae6d55fd6cbaa3166e44c0613bf9614371aa..4eb70ed6be533b0cf67b69c87fa6732f0ab4f9b3 100644 (file)
@@ -187,8 +187,17 @@ public:
   IntegerType() = default;
   /* implicit */ IntegerType(Type::ImplType *ptr);
 
+  /// Get or create a new IntegerType of the given width within the context.
+  /// Assume the width is within the allowed range and assert on failures.
+  /// Use getChecked to handle failures gracefully.
   static IntegerType get(unsigned width, MLIRContext *context);
 
+  /// Get or create a new IntegerType of the given width within the context,
+  /// defined at the given, potentially unknown, location.  If the width is
+  /// outside the allowed range, emit errors and return a null type.
+  static IntegerType getChecked(unsigned width, MLIRContext *context,
+                                Location location);
+
   /// Return the bitwidth of this integer type.
   unsigned getWidth() const;
 
index a431b0cae0498dfb4a1a04b1914a5312ede31f8b..d9d8691a0a68a58650fde2b287bdb304ccf2679b 100644 (file)
@@ -683,19 +683,38 @@ IndexType IndexType::get(MLIRContext *context) {
   return impl.indexType;
 }
 
-IntegerType IntegerType::get(unsigned width, MLIRContext *context) {
-  assert(width <= kMaxWidth && "admissible integer bitwidth exceeded");
+static IntegerType getIntegerType(unsigned width, MLIRContext *context,
+                                  llvm::Optional<Location> location) {
+  if (width > IntegerType::kMaxWidth) {
+    if (location)
+      context->emitError(*location, "integer bitwidth is limited to " +
+                                        Twine(IntegerType::kMaxWidth) +
+                                        " bits");
+    return {};
+  }
+
   auto &impl = context->getImpl();
 
   auto *&result = impl.integers[width];
   if (!result) {
     result = impl.allocator.Allocate<IntegerTypeStorage>();
-    new (result) IntegerTypeStorage{{Kind::Integer, context}, width};
+    new (result) IntegerTypeStorage{{Type::Kind::Integer, context}, width};
   }
 
   return result;
 }
 
+IntegerType IntegerType::getChecked(unsigned width, MLIRContext *context,
+                                    Location location) {
+  return getIntegerType(width, context, location);
+}
+
+IntegerType IntegerType::get(unsigned width, MLIRContext *context) {
+  auto type = getIntegerType(width, context, None);
+  assert(type && "failed to construct IntegerType");
+  return type;
+}
+
 FloatType FloatType::get(Kind kind, MLIRContext *context) {
   assert(kind >= Kind::FIRST_FLOATING_POINT_TYPE &&
          kind <= Kind::LAST_FLOATING_POINT_TYPE && "Not an FP type kind");
index a6083a651512efad5a2a5f5dddd4aa1bbf79aa6f..4dc9616f8aabd530fab6981bd1c6b09d2c40cf7a 100644 (file)
@@ -318,12 +318,9 @@ Type Parser::parseType() {
     auto width = getToken().getIntTypeBitwidth();
     if (!width.hasValue())
       return (emitError("invalid integer width"), nullptr);
-    if (width > IntegerType::kMaxWidth)
-      return (emitError("integer bitwidth is limited to " +
-                        Twine(IntegerType::kMaxWidth) + " bits"),
-              nullptr);
+    auto loc = getEncodedSourceLocation(getToken().getLoc());
     consumeToken(Token::inttype);
-    return builder.getIntegerType(width.getValue());
+    return IntegerType::getChecked(width.getValue(), builder.getContext(), loc);
   }
 
   // float-type