Refactor the asmparser hook to work with a new OperationState type that fully
encapsulates an operation that is yet to be created.  This is a patch towards
custom ops providing create methods that don't need to be templated, allowing
them to move out of line in the future.

PiperOrigin-RevId: 207725557
diff --git a/include/mlir/IR/Builders.h b/include/mlir/IR/Builders.h
index 59aca69..80b30c6 100644
--- a/include/mlir/IR/Builders.h
+++ b/include/mlir/IR/Builders.h
@@ -155,7 +155,8 @@
   // Add new basic block and set the insertion point to the end of it.
   BasicBlock *createBlock();
 
-  // Create an operation at the current insertion point.
+  // TODO(clattner): remove this.
+  /// Create an operation at the current insertion point.
   OperationInst *createOperation(Identifier name, ArrayRef<CFGValue *> operands,
                                  ArrayRef<Type *> resultTypes,
                                  ArrayRef<NamedAttribute> attributes) {
@@ -165,18 +166,23 @@
     return op;
   }
 
+  /// Create an operation given the fields represented as an OperationState.
+  OperationInst *createOperation(const OperationState &state);
+
+  // TODO(clattner): rework build to return an OperationState so the
+  // implementations can moved out of line.
+  /// Create operation of specific op type at the current insertion point.
+  template <typename OpTy, typename... Args>
+  OpPointer<OpTy> create(Args... args) {
+    return OpTy::build(this, args...);
+  }
+
   OperationInst *cloneOperation(const OperationInst &srcOpInst) {
     auto *op = srcOpInst.clone();
     block->getOperations().insert(insertPoint, op);
     return op;
   }
 
-  // Create operation of specific op type at the current insertion point.
-  template <typename OpTy, typename... Args>
-  OpPointer<OpTy> create(Args... args) {
-    return OpTy::build(this, args...);
-  }
-
   // Terminators.
 
   ReturnInst *createReturnInst(ArrayRef<CFGValue *> operands) {
@@ -256,6 +262,7 @@
   /// Get the current insertion point of the builder.
   StmtBlock::iterator getInsertionPoint() const { return insertPoint; }
 
+  // TODO(clattner): remove this.
   OperationStmt *createOperation(Identifier name, ArrayRef<MLValue *> operands,
                                  ArrayRef<Type *> resultTypes,
                                  ArrayRef<NamedAttribute> attributes) {
@@ -265,6 +272,11 @@
     return op;
   }
 
+  /// Create an operation given the fields represented as an OperationState.
+  OperationStmt *createOperation(const OperationState &state);
+
+  // TODO(clattner): rework build to return an OperationState so the
+  // implementations can moved out of line.
   // Create operation of specific op type at the current insertion point.
   template <typename OpTy, typename... Args>
   OpPointer<OpTy> create(Args... args) {